技术资料首页 >> 程序员专区 >> PHP专栏 >> PHP中的多线程与多进程

PHP中的多线程与多进程 (3)

2006-07-03 04:16:59作者: 来源:http://www.chinaunix.net/jh/27/661015.html 浏览次数:13 文字大小:【】【】【
于:2005-12-02 22:03:44

引用:原帖由 wobushiwo 于 2005-12-2 20:37 发表
php fork出来的子进程有那么特殊吗?

一般来说子会继承父的信息的

LZ的说明不继承,我估计是建立在他的上下文中,也就是局限在那代码的那个判断中的意思吧? 




可以有类似的意思。

他是做了一个全新的拷贝,将不和原来的再发生关系。


 HonestQiao 回复于:2005-12-02 22:04:51

引用:原帖由 wobushiwo 于 2005-12-2 20:39 发表
假如不局限在一种语言或环境中,我常是多语言混编

假如可以的话,我依靠OS,或者加上其他语言,而不会像LZ只用PHP去实现

MAYBE 我的 PHP太烂了 



这个,呵呵,仅仅是说在PHP之中的。

用其他的,C++作多线程无疑比这个好多了。

但是有些时候可能并不需要C++来参与。


 diychen 回复于:2005-12-04 13:52:07

楼上你的方式是什么呢?


 Haohappy 回复于:2005-12-05 16:27:08

引用:原帖由 hightman 于 2005-12-2 20:35 发表
可是 exec() 可以说是阻塞式的吧,  也就是说 exec() 要等它执行完才能执行后面的代码

这样就不符合要求了 




这里有一个技巧哦,推荐给这里的朋友们:
如果你执行的是
php -q ./test.php
就要执行完后再执行后面的代码

但是你可以这样做:
php -q ./test.php  > /dev/null  &

就可以了,不影响下面的代码继续执行。

呵呵,不明白的朋友可以自己google一下。

[ 本帖最后由 Haohappy 于 2005-12-6 11:26 编辑 ]


 wobushiwo 回复于:2005-12-05 19:15:43

引用:原帖由 Haohappy 于 2005-12-5 16:27 发表



这里有一个技巧哦,推荐给这里的朋友们:
如果你执行的是
php -q ./test.php
就要执行完后再执行后面的代码

但是你可以这样做:
php -q ./test.php  > /dev/null

就可以了,不影响下面的代码继 ... 




很遗憾,我GOOGLE后还是不明白,我只知道 >/dev/null 是把输出重定向了,不知道还有启动另一进程的

能力,请牛人明示


 Haohappy 回复于:2005-12-06 11:38:56

呵呵。还有一个&,不好意思。
$cmd= "php -q ./test.php  > /dev/null & "
$pid = exec($cmd);

-q 去掉php信息
> /dev/null 消除shell下的输出
& 后台执行

这三步就可以做到没有输出,也不影响下面的代码执行。

win下:
$wsh = new COM("WScript.Shell");
$phpobj = $wsh->Exec("php -q ./test.php ");
$pid = $phpobj->ProcessID;

有可能会引起杀毒软件的报警,呵呵。


 wobushiwo 回复于:2005-12-06 11:40:16

引用:原帖由 wobushiwo 于 2005-12-2 20:38 发表
不好意思,是 + & 




请看 13 楼


 dulao5 回复于:2006-06-02 11:38:43

除了fork, cli下的并发方式还有一种,看我的例子:


php不支持多线程,但是我们可以把问题转换成“多进程”来解决。由于php中的pcntl_fork只有unix平台才可以使用,所以本文尝试使用popen来替代。

 
下面是一个例子:
 
被并行调用的子程序代码:

<?php
 
if($argc==1){
echo("argv\n");
}
 
$arg = $argv[1];
 
for($i=0; $i<10; $i++)
{
 
echo($i.".1.".time()." exec $arg \n");
if($arg=='php2')
{
sleep(1);
echo($i.".2.".time()." exec $arg \n");
sleep(1);
}
else
sleep(1);
}
 
 
?>
 

----------------------------
 
主调用者程序,由他调用子进程,同时并发的收集子程序的输出
 

<?php
error_reporting(E_ALL);
 
 
$handle1 = popen('php sub.php php1', 'r');
$handle2 = popen('php sub.php php2', 'r');
$handle3 = popen('php sub.php php3', 'r');
 
 
echo "'$handle1'; " . gettype($handle1) . "\n";
echo "'$handle2'; " . gettype($handle2) . "\n";
echo "'$handle3'; " . gettype($handle3) . "\n";
 
//sleep(20);
 
while(!feof($handle1) || !feof($handle2) || !feof($handle3) )
{
 
$read = fgets($handle1);
echo $read;
 
$read = fgets($handle2);
echo $read;
 
$read = fgets($handle3);
echo $read;
}
 
pclose($handle1);
pclose($handle2);
pclose($handle3);
?>
 

-------------------
下面是我机器上的输出:

C:\my_hunter>php exec.php
'Resource id #4'; resource
'Resource id #5'; resource
'Resource id #6'; resource
0.1.1147935331 exec php1
0.1.1147935331 exec php2
0.1.1147935331 exec php3
1.1.1147935332 exec php1
0.2.1147935332 exec php2
1.1.1147935332 exec php3
2.1.1147935333 exec php1
1.1.1147935333 exec php2
2.1.1147935333 exec php3
3.1.1147935334 exec php1
1.2.1147935334 exec php2
3.1.1147935334 exec php3
4.1.1147935335 exec php1
2.1.1147935335 exec php2
4.1.1147935335 exec php3
5.1.1147935336 exec php1
2.2.1147935336 exec php2
5.1.1147935336 exec php3
6.1.1147935337 exec php1
3.1.1147935337 exec php2
6.1.1147935337 exec php3
7.1.1147935338 exec php1
3.2.1147935338 exec php2
7.1.1147935338 exec php3
8.1.1147935339 exec php1
4.1.1147935339 exec php2
8.1.1147935339 exec php3
9.1.1147935340 exec php1
4.2.1147935340 exec php2
9.1.1147935340 exec php3
5.1.1147935341 exec php2
5.2.1147935342 exec php2
6.1.1147935343 exec php2
6.2.1147935344 exec php2
7.1.1147935345 exec php2
7.2.1147935346 exec php2
8.1.1147935347 exec php2
8.2.1147935348 exec php2
9.1.1147935349 exec php2
9.2.1147935350 exec php2

 
 
**总结:**
 
**主程序循环等待子进程, 通过fgets或fread 把子进程的输出获取出来 , 从时间戳上看,的确实现了并发执行。**
 
-----------------------------------------------
以后的改进:
 
*  popen打开的句柄是单向的,如果需要向子进程交互,可以使用proc_open
*  使用数组和子函数代替while(!feof($handle1) || !feof($handle2) || !feof($handle3) )这种龌龊的写法
*  用fread一次把子进程已经产生的输出取完,而不是每次一行。

------------------
我的blog : http://dulao5.blog.hexun.com/3726837_d.html

[ 本帖最后由 dulao5 于 2006-6-2 11:39 编辑 ]


 dulao5 回复于:2006-06-02 11:45:41

一个并发执行shell任务的调度者,本程序读取一个任务文件,把里面的每行命令并发执行, 可以设置同时存在的子进程数目:


<?
/*
   主任务管理器
   并发的执行子任务列表
 */

include("../common/conf.php");
include("../common/function.php");

//开启的进程数
$exec_number = 40 ;



/***** main ********/
if($argc==1){
    echo("argv\n");
}
$taskfile = $argv[1];

//tasklist
$tasklist = file($taskfile);

$tasklist_len = count($tasklist);
$tasklist_pos = 0;

$handle_list = array();



while(1)
{

   
[1] [2] [3] [4]

相关文章