2011-04-06 43 views
0

我试着去创建计数器,使用共享块存储器,只是看代码:PHP共享块存储和叉

$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; 
    } 
} 

而IL得到奇怪的结果

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 

我想创建这个类在多线程中读取和写入文件中的字符串。

回答

1

你没有结束的子进程可言,他们永远不会结束。你也没有检查过程是否正确分叉,没有控制什么是完成处理和按什么顺序。分叉进程并不是其他语言提供的多线程,所发生的一切就是当前进程正在被复制并且变量被共享 - 您的$ 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 
     } 
    } 
} 
0

你是不是您的来电pcntl_fork后处理的PID。你的叉子是分叉的,因为循环继续执行和分叉。

除非你想创建一个本地化的fork炸弹,你可能不希望自己的叉子派生。

我做了一些工作,在当地,试图弄清楚,如果单独可以解决这个问题,但事实并非如此。它几乎看起来像共享内存段没有被正确写入,就好像字符串两边的数字之一正在被重复,这会破坏所有的数据并强制重新开始。

完整的猜测。

你可能要考虑用PHP进行并行处理的方式不同。使用Gearman作为多进程工作队列是我的最爱解决方案。