您的位置:首页 > 编程语言 > PHP开发

pcntl_fork安装以及实现PHP多进程

2014-03-12 17:17 531 查看
PHP有个pcntl_fork的函数可以实现多进程,但要加载pcntl拓展,而且只有在linux下才能编译这个拓展,有时间在ubuntu下玩了下。

1.首先在ubuntu下编译pcntl.so,我的ubuntu下找不到pcntl的包,于是

创建一个文件夹下载了整个PHP包,在里面找到了pcntl包运行如下命令

# mkdir php

# cd php

# apt-get source php5

# cd php5-(WHATEVER_RELEASE)/ext/pcntl

# phpize

# ./configure (注一)

# make

# make install

phpize 命令是用来准备 PHP 外挂模块的编译环境的。

成功的安装将建立 extname.so 并放置于 PHP 的外挂模块目录中 (预设存放于 /usr/lib/php/modules/ 内) 。

需要调整 php.ini,加入 extension=extname.so 这一行之后才能使用此外挂模块。

2,开始实验pcntl_fork

01
<?php
02
//while(1)//循环采用3个进程
03
//{
04
//declare(ticks=1);
05
$bWaitFlag
=
FALSE;
//
是否等待进程结束
06
//$bWaitFlag
=TRUE;// 是否等待进程结束
07
$intNum
=
3;
//
进程总数
08
$pids
=
array
();
//
进程PID数组
09
for
(
$i
=
0;
$i
<
$intNum
;
$i
++)
10
{
$pids
[
$i
]
=pcntl_fork();
//
产生子进程,而且从当前行之下开试运行代码,而且不继承父进程的数据信息
11
/*if($pids[$i])//父进程
12
{
13
//echo
$pids[$i]."parent"."$i ->" .time()."\n";
14
}
15
*/
16
if
(
$pids
[
$i
]
==-1)
17
{
18
echo
"couldn't
fork"
.
"\n"
;
19
}
20
elseif
(!
$pids
[
$i
])
21
{
22
sleep(1);
23
echo
"\n"
.
"第"
.
$i
.
"个进程
->"
.
time().
"\n"
;
24
//$url=" http://xxx/comments.php?p=".$i;//抓取页面的例子
25
//$content
=file_get_contents($url);
26
//file_put_contents('message.txt',$content);
27
//echo
"\n"."第".$i."个进程 ->" ."抓取页面".$i."->" .time()."\n";
28
exit
(0);
//子进程要exit否则会进行递归多进程,父进程不要exit否则终止多进程
29
}
30
if
(
$bWaitFlag
)
31
{
32
pcntl_waitpid(
$pids
[
$i
],
$status
,
WUNTRACED);
echo
"wait
$i ->"
.
time() .
"\n"
;}}
33
//sleep(1);
34
//}
35
?>
保存为fork.php 在命令行运行 php fork.php



pcntl函数还有一些功能没实验,例如进程状态,根据相应状态进行一些处理,运用多进程可以增加处理数据的效

率。在网上看到的fork的解释:

fork之后,操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但 是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,但只有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程会返回错误。

可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,他们分别作不同的工作,也就是分岔了。这也是fork为什么叫fork的原因。

至于那一个最先运行,可能与操作系统有关,而且这个问题在实际应用中并不重要,如果需要父子进程协同,可以通过原语的办法解决。

----------------------------------------------

fork前父进程的东西子进程可以继承,而在fork后子进程没有任何和父进程的继承关系了。在子进程里创建的东西是子进程的,在父进程创建的东西是父进程的。可以完全看成两个进程。

----------------------------------------------

在程序段里用了fork();之后程序出了分岔,派生出了两个进程。具体哪个先运行就看该系统的调度算法了。

在这里,我们可以这么认为,在运行到”pid=fork();”时系统派生出一个跟主程序一模一样的子进程。该进程的”pid=fork();”一句中 pid得到的就是子进程本身的pid;子进程结束后,父进程的”pid=fork();”中pid得到的就是父进程本身的pid。因此改程序有两行输出。

----------------------------------------------

fork()函数复制了当前进程的PCB,并向父进程返回了派生子进程的pid。而且根据上面”corand”兄的提示,父子进程并行,打印语句的 先后完全看系统的调度算法。打印的内容控制则靠pid变量来控制。因为我们知道fork()向父进程返回了派生子进程的pid,是个正整数;而派生子进程 的pid变量并没有被改变。这一区别使得我们看到了他们的不同输出。

----------------------------------------------

1,派生子进程的进程,即父进程,其pid不变;

2,对子进程来说,fork返回给它0,但它的pid绝对不会是0;之所以fork返回0给它,是因为它随时可以调用getpid()来获取自己的pid;

3,fork之后父子进程除非采用了同步手段,否则不能确定谁先运行,也不能确定谁先结束。认为子进程结束后父进程才从fork返回的,这是不对的,fork不是这样的,vfork才这样。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php php5