douzhai7873 2014-03-07 08:22
浏览 41
已采纳

PHP pthreads很奇怪

sorry for my twisted english - it is not my native.

I have a trouble: pthreads works, but in some strange way: for example, I cannot do "echo" from a thread.
Some example code from the internet:

<?php
    ini_set('display_errors',E_ALL);
    class hashThread extends Thread {
    private $max = 1;
    private $index = 0;
    function __construct($max, $index)
    {
        $this->max = $max;
        $this->index = $index;
    }
    public function run()
    {
        for ($i=1; $i<=$this->max; $i++)
        {
            md5($i);
        }
        error_log("Thread #{$this->index} finished
");
        echo "Thread #{$this->index} finished
";
    }
    }
    $thread_count = 8;
    $start_time = microtime(true);
    for($i=1; $i<=$thread_count; $i++)
    {
    $thread[$i] = new hashThread(1e6, $i);
    $thread[$i]->start(PTHREADS_INHERIT_NONE);
    }
    echo "Done in: " . round(microtime(true) - $start_time, 2) . " seconds";
?>

Script shows only "Done in: 0.14 seconds" (in webpage), no echoes, But! it is in error log:

$ tail -f /var/log/nginx/error_log | grep Thread
2014/03/07 08:05:10 [error] 12621#0: *2818394 FastCGI sent in stderr: "PHP message: Thread #2 finished" ...
2014/03/07 08:05:10 [error] 12621#0: *2818394 FastCGI sent in stderr: "PHP message: Thread #1 finished" ...
2014/03/07 08:05:10 [error] 12621#0: *2818394 FastCGI sent in stderr: "PHP message: Thread #3 finished" ...
2014/03/07 08:05:10 [error] 12621#0: *2818394 FastCGI sent in stderr: "PHP message: Thread #6 finished" ...
2014/03/07 08:05:10 [error] 12621#0: *2818394 FastCGI sent in stderr: "PHP message: Thread #5 finished" ...
2014/03/07 08:05:10 [error] 12621#0: *2818394 FastCGI sent in stderr: "PHP message: Thread #7 finished" ...
2014/03/07 08:05:10 [error] 12621#0: *2818394 FastCGI sent in stderr: "PHP message: Thread #4 finished" ...
2014/03/07 08:05:10 [error] 12621#0: *2818394 FastCGI sent in stderr: "PHP message: Thread #8 finished" ...

In fact, I don't use any echo in my threads, I need to aggregate some webservices (each webservice class = thread), wait for the slowest thread, and merge all results to one array that could be taken from outside, but I never worked with threads in PHP or other languages before. I would appreciate if you give me some example. Thank you.

Software:
Gentoo x86
PHP 5.4.23 (nginx configured to use php-fpm)
Nginx 1.4.4

No apache. PHP built threadsafe, pthreads module is enabled.

  • 写回答

2条回答 默认 最新

  • douwei2966 2014-03-07 09:19
    关注

    Standard output cannot be guaranteed, Zend provides no API to ensure you get the right stream, it cannot because of all the environments it works in, it is left to the software above PHP in your stack, FPM does count as above PHP in the stack, it does strange things with stderr/stdout - it has to in order to work at all.

    So, don't do that !

    As mentioned there's not really any need to write standard output anyway, if you want to log, then write a logger for files :)

    Here's your starting place:

    Read the articles in the Documentation section of that readme. The first explains exactly how pthreads manages to exist and how it works and will give you a good foundation of knowledge.

    The second describes the highest level of threading that we have right now, which is Pooling, you can skip that one ... I wouldn't :)

    Please do the reading, it will be of enormous help ...

    While you're reading and understanding, here is a semi-relevant example code listing which fetches pages from a few locations and stores the result in a shared array which the main thread can then process:

    <?php
    /*
     Just a container class, nothing to see here
    */
    class Store extends Stackable {
        public function run(){}
    }
    
    class Hash extends Thread {
        /*
        * Take shared storage and target for fetching
        */
        public function __construct(Store $store, $target) {
            $this->store = $store;
            $this->target = $target;
        }
    
        /*
        * Fetch contents of target and store associatively in Store
        */
        public function run() {
            $this->store[$this->target] = file_get_contents(
                $this->target);
        }
    
        protected $store;
        protected $target;
    }
    
    /* will hold shared data */
    $store   = new Store();
    /* will hold threads */
    $threads = [];
    $thread  = 0;
    
    /* create and start all threads */
    while ($thread < 4) {
        $threads[$thread] = new Hash($store, sprintf(
            "http://www.google.co.uk/?q=%s", md5(mt_rand()*microtime())));
        $threads[$thread]->start();
        $thread++;
    }
    
    /* join all threads */
    foreach ($threads as $thread)
        $thread->join();
    
    foreach ($store as $target => $data)
        printf("%s returned %d bytes
    ", $target, strlen($data));
    ?>
    

    By the time you get to here, you should have read every word I have written about pthreads, hopefully :)

    You're now ready to see a more complex but more relevant example of the kind of activity you are undertaking, the following is some code written for someone else on SO, it uses DOM/XPath to fetch documentation descriptions from phpdocs ...

    https://gist.github.com/krakjoe/b1526fcc828621e840cb

    I think that should be enough code and documentation for one day, right ??

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么