0

我正在尝试用 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。注意:我从本网站的其他帖子中获得了代码: 检查一下

提前谢谢了。

4

2 回答 2

1

嗯...查看时间戳,看起来它们都是同时开始的(下午 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

我错过了什么吗?

我确实看到他们在睡觉之前不会打印出来。

于 2013-10-25T15:42:29.737 回答
1

正如 Horse Smith 所提到的,时间戳表明执行确实是同时开始的。当您从多个线程打印到输出时,您很幸运能够读取它,没关系对数据的顺序有意义......如果数据的顺序至关重要,那么您真的应该使用互斥锁进行打印。

另一件事,sleep() 不适合在多线程应用程序中使用——理论上,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 带有高级同步,您应该致力于在任何实际代码中使用它。

参考:

于 2013-10-25T19:26:49.037 回答