ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

PHP线程应如何存储其数据?

2019-10-11 04:31:12  阅读:195  来源: 互联网

标签:php multithreading pthreads php-7-1


所以我一直在网上搜索和阅读有关PHP pthreads3以及它们应该如何存储数据的信息. (或更确切地说,它们不是)
在我看来,线程正确存储其数据的唯一方法是创建一个新的Threaded对象并将其发送给线程.然后,线程可以使用此Threaded对象存储几乎所有数据.

我的问题,也是掌握PHP线程的最大问题:
是否可以在需要时让线程创建自己的存储对象?
我不知道如何或为什么,因为我在此找到的所有答案都含糊不清,详尽而令人困惑,“也许,但没有”,主要与性能差和内存问题/安全性有关.
这似乎应该可行,无论如何:

class someFantasticThread extends Thread {
    public $someData;

    function run(){
        while(true){
            //Create a fresh storage for the new data this iteration
            $this->someData = new SomeCoolStorage(); // Can this work somehow without all the issues?
            $this->someData[] = 'amazingdata'; // Do something amazing and store the new results in $someData
            $this->someData[] = new SomeCoolStorage(); // This would also be desireable, if it can somehow be done
            //don't mind the obvious loop issues. Imagine this is a well formed loop
        }
    }
}

class SomeCoolStorage extends Threaded{}

// Start the thread
$threadObj = new someFantasticThread();
$threadObj->start();
while(true){
    // at some point, retrieve the data and do something useful with the contained results
    // doSomethingAwesome($threadObj->someData);
}

解决方法:

It seems to me that the only way for a thread to store its data properly is to create a new Threaded object and send it to the thread.

是的,这是一种方法.

Is it possible to have the thread create its own storage objects when it wants?

是的,但前提是您必须在该线程(或它可能产生的任何子线程)中对其进行操作.

在PHP中使用线程时要理解的基本知识之一是,Threaded类的对象与创建它们的上下文相关.这意味着,如果您在主线程中创建一个Threaded对象,将该对象传递给一个生成的子线程,然后加入该生成的子线程,那么您可以继续正常使用该Threaded对象.

示例1(构造函数注入):

<?php

$store = new Threaded(); // created in the main thread

$thread = new class($store) extends Thread {
    public $store;

    public function __construct(Threaded $store)
    {
        $this->store = $store;
    }

    public function run()
    {
        $this->store[] = 1;
        $this->store[] = 2;
    }
};

$thread->start() && $thread->join();

print_r($store); // continue using it in the main thread

这将输出:

Threaded Object
(
    [0] => 1
    [1] => 2
)

在上面的示例中,我们还可以在构造函数内部创建Threaded对象,然后执行var_dump($thread-> store);在脚本末尾.之所以可行,是因为Threaded对象仍在需要它的最外层范围中创建,因此它并不与可能已经被破坏的任何子线程的范围相关. (PHP中唯一在单独的线程中执行的线程的一部分是Thread :: run方法.)

与以上示例类似,我们也可以使用setter注入. (不过,同样,只要在将使用Threaded对象的最外部作用域中的线程调用setter即可.)

许多不熟悉PHP线程开发的开发人员似乎遇到的问题是,他们从新线程内部创建Threaded对象,然后期望在加入同一线程时能够使用该Threaded对象.

例:

<?php

$thread = new class() extends Thread {
    public $store;

    public function run()
    {
        $this->store = new Threaded(); // created inside of the child thread
        $this->store[] = 1;
        $this->store[] = 2;
    }
};

$thread->start() && $thread->join();

print_r($thread->store); // attempt to use it in the outer context (the main thread)

这将输出:

RuntimeException: pthreads detected an attempt to connect to an object which has already been destroyed in %s:%d

这是因为加入生成的子线程时,$thread-> store中的Threaded对象已被破坏.这个问题也可能更加微妙.例如,在Threaded对象内部创建新数组将自动将其强制转换为Volatile对象(也是Threaded对象).

这意味着以下示例也不起作用:

<?php

$thread = new class() extends Thread {
    public $store;

    public function run()
    {
        $this->store = [];
        $this->store[] = 1;
        $this->store[] = 2;
    }
};

$thread->start() && $thread->join();

print_r($thread->store);

输出:

RuntimeException: pthreads detected an attempt to connect to an object which has already been destroyed in %s:%d

回到示例代码,您的工作绝对没问题,但前提是您不尝试在该子线程之外使用$this-> someData.

标签:php,multithreading,pthreads,php-7-1
来源: https://codeday.me/bug/20191011/1890166.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有