2013-10-25 9 views
0

我想用php实现multi_threading程序,我已经下载了pthread包并做了所有必需的配置。 然后我试图运行此代码:线程不能在php5中一起工作

<?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。 注:我从本网站的其他帖子得到的代码: check it up

非常感谢提前。

+0

[pthreads for PHP apache不执行并行线程]可能的重复(http://stackoverflow.com/questions/15156503/pthreads-for-php-apache-not-execute-parallel-threads) – DaveRandom

回答

1

正如Horse Smith所提到的那样,时间戳表明执行过程同时开始。当你从多个线程打印输出时,你很幸运能够读取它,而不需要根据数据的顺序来理解......如果数据的顺序非常重要,那么你真的应该使用互斥锁打印。另一件事,sleep()不适合在多线程应用程序中使用 - 理论上,睡眠是针对进程的,并且应该导致整个进程进入休眠状态。我在理论上说,因为posix是同一个想法的百万实现,然后有窗口要考虑,我没有足够的经验与Windows提供良好的建议,但你不应该依赖它的行为...

的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来清除它们对你来说,这是一个很好的习惯中是在,因为它保持一切与你期待的方式保持同步。

即使是休眠状态,对于使用多线程的实际生产代码来说也不够好,问题在于,它不会让线程处于接受状态:其他线程不会影响它,如果您指示线程睡了半个小时,没有什么可以做的(这是优雅的)来唤醒它。pthreads带有高级别的同步,你应该在任何实际的代码中使用它。

参考文献:

+0

我正在尝试使用线程来模拟随机用户的行为,所以我需要让他们并行工作,并得到一个随机的有序输出,你能解释我怎么能在我的情况下使用互斥体获得理想的跑步? - 注意:当我使用xampp shell CMD for windows运行页面时,我得到了所需的输出,因此,浏览器出现问题了吗?很多thanx :) – Rawan

+0

他们正在并行工作......你不应该在apache安装程序中编写线程的标准输出,这很危险,并且会影响输出的顺序。 –

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 

我是否错过了什么?

我确实看到他们在他们完成睡眠之前不打印出来。

+0

是的:(确切地说..他们一起开始,但为什么不打印下一个线程的起始行,直到打印出前一行的“完成”行为止!为什么它在等待呢?很多thanx :) – Rawan