我正在尝试用php实现multi_threading程序,我已经下载了pthread包并完成了所有必需的配置。然后我尝试运行以下代码:
<?php
class AsyncOperation extends Thread {
public function __construct($arg) {
$this->arg = $arg;
}
public function run() {
if ($this->arg) {
$sleep = mt_rand(1, 10);
printf('%s: %s -start -sleeps %d' . "'n", date("g:i:sa"), $this->arg, $sleep);
sleep($sleep);
printf('%s: %s -finish' . "'n", date("g:i:sa"), $this->arg);
}
}
}
// Create a array
$stack = array();
//Iniciate Miltiple Thread
foreach ( range("A", "D") as $i ) {
$stack[] = new AsyncOperation($i);
}
// Start The Threads
foreach ( $stack as $t ) {
$t->start();
}
?>
但是每次我运行代码时,我都会得到这样的结果:
4:29:47pm: A -start -sleeps 1
4:29:48pm: A -finish
4:29:47pm: C -start -sleeps 3
4:29:50pm: C -finish
4:29:47pm: D -start -sleeps 4
4:29:51pm: D -finish
4:29:47pm: B -start -sleeps 7
4:29:54pm: B -finish
另一次运行:
5:29:21pm: A -start -sleeps 1
5:29:22pm: A -finish
5:29:21pm: B -start -sleeps 3
5:29:24pm: B -finish
5:29:21pm: D -start -sleeps 8
5:29:29pm: D -finish
5:29:21pm: C -start -sleeps 9 5:29:30pm: C -finish
如您所见,问题在于线程似乎没有同时工作,每当线程启动时,在完成之前没有其他线程启动。 我注意到的令人不安的事情是线程总是从最小的睡眠时间开始排序!
我希望有些像这样运行:
12:00:06pm: A -start -sleeps 5
12:00:06pm: B -start -sleeps 3
12:00:06pm: C -start -sleeps 10
12:00:06pm: D -start -sleeps 2
12:00:08pm: D -finish
12:00:09pm: B -finish
12:00:11pm: A -finish
12:00:16pm: C -finish
有人可以告诉我如何获得通缉的运行吗?我正在使用php5。注意:我从本网站的其他帖子中获得了代码:检查一下
提前非常感谢。
正如 Horse Smith 所提到的,时间戳表明执行确实在同一时间开始。当您从多个线程打印到输出时,您很幸运能够读取它,没关系从数据的顺序中解脱出来......实际上,如果数据的顺序至关重要,您应该使用互斥锁进行打印。
另一件事,sleep() 不适合在多线程应用程序中使用 - 理论上,睡眠是针对进程的,应该导致整个过程休眠。我从理论上说,因为posix是同一想法的一百万个实现,然后有窗口需要考虑,我对窗口没有足够的经验来提供合理的建议,但你不应该依赖它的行为......
usleep 函数更适合线程:
<?php
class AsyncOperation extends Thread {
public function __construct($arg) {
$this->arg = $arg;
}
public function run() {
if ($this->arg) {
$sleep = mt_rand(1, 10);
printf('%s: %s -start -sleeps %d' . "'n", date("g:i:sa"), $this->arg, $sleep);
usleep($sleep*1000000);
printf('%s: %s -finish' . "'n", date("g:i:sa"), $this->arg);
}
}
}
// Create a array
$stack = array();
//Iniciate Miltiple Thread
foreach ( range("A", "D") as $i ) {
$stack[] = new AsyncOperation($i);
}
// Start The Threads
foreach ( $stack as $t ) {
$t->start();
}
foreach ($stack as $t)
$t->join();
?>
此外,你应该加入线程,不允许 php 为你清理它们,这是一个很好的兔子,因为它使一切保持同步,就像你期望的那样。
即使是 usleep,对于使用多线程的实际生产代码来说也不够好,问题在于 usleep 它不会让线程处于接受状态:没有其他线程可以影响它,如果你指示一个线程休眠半小时,你无能为力(这是优雅的)来唤醒它。 pthreads 具有高级同步, 您应该在任何实际代码中使用。
引用:
- http://php.net/pthreads
- http://php.net/Thread.wait
- http://php.net/Thread.notify
- http://php.net/Thread.synchronized
- https://gist.github.com/krakjoe/6437782
嗯...查看时间戳,看起来它们都是同时开始的(下午 4:29:47):
4:29:47pm: A -start -sleeps 1
4:29:48pm: A -finish
4:29:47pm: C -start -sleeps 3
4:29:50pm: C -finish
4:29:47pm: D -start -sleeps 4
4:29:51pm: D -finish
4:29:47pm: B -start -sleeps 7
4:29:54pm: B -finish
与此相同(下午 5:29:21):
5:29:21pm: A -start -sleeps 1
5:29:22pm: A -finish
5:29:21pm: B -start -sleeps 3
5:29:24pm: B -finish
5:29:21pm: D -start -sleeps 8
5:29:29pm: D -finish
5:29:21pm: C -start -sleeps 9
5:29:30pm: C -finish
我错过了什么吗?
我确实看到他们在睡觉之前不会打印出来。