php多进程

    前不久写了一个简单的不用php redis扩展的redis队列(原理是socket和redis的通讯协议RESP),里面有个开始队列的函数,执行的是rpop存储在redis的列表数据。想优化一下这里的代码,不是一个一个地rpop,而是开启多个进程执行rpop。多线程和多进程的概念不再描述了,多进程可以了解一下php-fpm(FastCGI进程管理器),但是这里也不是用这个;据我了解,php是没有多线程这个概念的.....刚开始我都不知道php可以是多进程的呢。

    pcntl_fork(),就是fork一个子进程,fork后面的代码个人理解是拷贝了两份一样的代码执行。fork>0返回子进程的pid是主进程,0的话是子进程,不是完美主义者(什么主进程没加pcntl_wait,子进程会变成僵尸进程),也不是想细说什么技术道理(你怎么不讲fork什么原理),这些稍微理解一下但又理解不透彻的东西,就不讨论了,只是探讨我发现的一些问题。

public function start(){
    $fork = pcntl_fork();
    if ($fork < 0) {
        var_dump('fork 子进程失败');
    } elseif ($fork) {
        //父进程
        var_dump('父进程开始任务');
        $this->pop();
        var_dump('父进程完成任务,sleep 2秒');
        sleep(2);
    } else {
        // 子进程
        var_dump('子进程开始任务');
        $this->pop();
        var_dump('子进程完成任务,sleep 2秒');
        sleep(2);
    }
}

    多次运行后,并不是我想要的结果,输出的数据有时还会叠在一起。考虑到的情况是redis两次返回的结果被同一个fread读取到了。

php多进程_第1张图片

    这不好办吗,子进程或者主进程稍微sleep一下就好啦

public function start(){
    $fork = pcntl_fork();
    if ($fork < 0) {
        var_dump('fork 子进程失败');
    } elseif ($fork) {
        //父进程
        var_dump('父进程开始任务');
        $this->pop();
        var_dump('父进程完成任务,sleep 1秒');
        sleep(1);
    } else {
        // 子进程
        usleep(100);//稍微sleep一下
        var_dump('子进程开始任务');
        $this->pop();
        var_dump('子进程完成任务,sleep 2秒');
        sleep(2);
    }
}

    稍微sleep一下的话,出现重叠的概率少了,但是redis那边read的时候还是会重叠,到现在都没有解决这个问题。仔细想想的话,这里100个同时请求redis里的数据,redis还不是要一个一个地执行?还不如一次性取所有的数据(redis的管道),所以突然放弃研究这个问题了。然后想到另外一个问题,如果我要先执行子进程再执行父进程要怎么控制呢?又涉及到进程间的通讯。

    进程间如何通讯这个也不细说了,信号,管道,共享内存,消息队列网上搜一下很多。我这里只是想讨论如何控制父子进程的执行顺序,我想到的是用管道,stream_socket_pari(),管道0写入数据,管道1读取数据,一个进程fread管道1阻塞等待另一个进程向管道0fwrite写入数据。

    该代码的逻辑就是fork两个进程,一个进程写入a,写完后另一个进程写入b。聪明的你应该已经知道如果要顺序执行的话,为什么要fork两个进程?是的,这两个例子我都觉得多此一举,但是这些是我亲自实践后才知道这样为什么不行,而且说不定这种思想以后会用到别的地方,最重要的是这过程中学到更多的之前不懂的知识,还有引出一个很重要的东西,socket,几乎哪里都能用到socket,接下来就是要研究这个东西了。

你可能感兴趣的:(php)