PHP pthreads-在线程之间共享实例变量

时间:2019-01-26 13:46:15

标签: php multithreading

我正在尝试在所有线程之间建立某种共享类。但是,我不确定如何使它可靠。

这是我的示例测试代码。基本上,它创建100个线程,为它们分配唯一的ID,将它们的引用传递给共享类实例并启动它们。在每个线程的run方法开始时,共享实例的共享计数器增加,并且线程的ID附加到共享数组。在run方法结束时,将减少计数器,并从数组中删除id元素。每个线程重复10次,以使其更可能导致错误。

在所有线程结束之后,预期结果是$ iCount = 0和空数组$ aArr。对于数组,这是可靠的方法,但对于$ iCount变量而言则不是。

class Shared extends \Threaded{
    private $aArr = [];
    private $iCount = 0;

    public function add($s){
        $this->iCount++;
        $this->aArr[] = $s;
    }

    public function remove($s){
        $this->iCount--;

        foreach($this->aArr as $iKey => $iId){
            if($iId == $s){
                unset($this->aArr[$iKey]);
            }
        }
    }

    public function dump(){
        var_dump('$this->iCount: ' . $this->iCount);
        var_dump('sizeof($this->aArr): ' . sizeof($this->aArr));
    }
}

class someThread extends \Thread{

    private $Shared;
    private $iId;

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


    public function setShared( $shared): void
    {
        $this->Shared = $shared;
    }

    public function run()
    {
        for($x = 0;$x < 10;$x++){
            $this->Shared->add($this->iId);

            usleep(rand(400000,500000));

            $this->Shared->remove($this->iId);
        }
    }

}

$shared = new Shared();

$threads = [];
for($x = 0;$x < 100;$x++){
    $thread = new someThread($x);
    $thread->setShared($shared);
    $thread->start();

    $threads[] = $thread;
}

foreach($threads as $t){
    $t->join();
}

$shared->dump();

多次执行此代码的结果是:

Execution 1:
string(17) "$this->iCount: 21"
string(22) "sizeof($this->aArr): 0"

Execution 2:
string(17) "$this->iCount: 14"
string(22) "sizeof($this->aArr): 0"

Execution 3:
string(16) "$this->iCount: 9"
string(22) "sizeof($this->aArr): 0"

因此,看起来原始int“ $ iCount”不是线程安全的,而数组“ $ aArr”是线程安全的。为什么?以及如何使跨线程的安全整数(作为类实例的成员)计数?

0 个答案:

没有答案