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 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
  • ¥20 yolov5自定义Prune报错,如何解决?