我试图创建计数器,使用共享块内存,只是看代码:
$i=0; $counter = new counter('g');
while($i<3){
$pid = pcntl_fork();
echo $counter->get()."'t".$i."'t".$pid."'n";
$i++;
}
class counter {
protected static $projID = array();
protected $t_key;
protected $length;
function __construct($projID){
!in_array( $projID, self::$projID) or die('Using duplicate project identifer "'.$projID.'" for creating counter');
self::$projID[] = $projID;
$this->t_key = ftok(__FILE__, $projID);
$this->shmid = shmop_open($t_key, 'c', 0755, 64);
$this->length = shmop_write($this->shmid, 0, 0);
shmop_close($this->shmid);
}
function get(){
$sem = sem_get($this->t_key, 1);
sem_acquire($sem);
$shmid = shmop_open($this->t_key, 'c', 0755, 64);
$inc = shmop_read($shmid, 0, $this->length);
$this->length = shmop_write($shmid, $inc+1, 0);
shmop_close($shmid);
sem_release($sem);
return $inc;
}
}
但是会得到奇怪的结果
7 0 2567
8 1 2568
9 0 0
1 1 0
2 2 2569
40 1 2570
4 2 2572
3 2 0
51 2 2571
52 1 0
63 2 0
5 2 0
64 2 2573
65 2 0
我想创建这个类用于在多线程中读写文件中的字符串。
您根本没有结束子进程,它们永远不会完成。您也没有检查进程是否正确分叉,无法控制哪些进程以何种顺序完成了处理。fork进程并不是其他语言提供的多线程,所发生的一切都是当前进程被复制和变量被共享——你的$i不会在3结束,也没有保证哪个进程第一个或最后一个完成。
试一试:
while($i < 3)
{
$pid = pcntl_fork();
if($pid == -1)
{
// some sort of message that the process wasn't forked
exit(1);
}
else
{
if($pid)
{
pcntl_wait($status); // refer to PHP manual to check what this function does
}
else
{
// enter your code here, for whatever you want to be done in parallel
// bear in mind that some processes can finish sooner, some can finish later
// good use is when you have tasks dependent on network latency and you want
// them executed asynchronously (such as uploading multiple files to an ftp or
// synchronizing of something that's being done over network
// after you're done, kill the process so it doesn't become a zombie
posix_kill(getmypid(), 9); // not the most elegant solution, and can fail
}
}
}
您在调用pcntl_fork
后不处理PID。您的分叉正在分叉,因为循环继续执行并分叉。
除非你想创建一个本地化的分叉炸弹,否则你可能不希望你的分叉分叉。
我在当地做了一些工作,试图弄清楚是否仅凭这一点就能解决问题,但没有。看起来好像没有正确地写入共享内存段,就好像字符串两边的一个数字被重复了,这会破坏所有的内存段,并迫使事情重新开始。
完整的猜测。
您可能需要考虑使用PHP执行并行处理的另一种方式。使用Gearman作为多进程工作队列是我最喜欢的解决方案。