2017-06-26 7 views
1

私はインターネットでPHPのpthreads3に関する情報を拾い読みしています。どのようにデータを保存することになっていますか? (またはむしろ、どういうわけか) スレッドがデータを適切に格納する唯一の方法は、新しいThreadedオブジェクトを作成してスレッドに送ることです。スレッドは、このThreadedオブジェクトを使用してほぼすべてのデータを格納できます。PHPスレッドはデータをどのように格納する必要がありますか?

私の質問と、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); 
} 
+0

このコードをどのような環境で使用する予定ですか? PHPスレッドはWebサーバー環境と互換性がないため、使用することはほとんどありません。 – duskwuff

+0

私はこのことを、私が尋ねていることを実行できるあらゆる環境で使用することを望んでいます。つまり、スレッドが独自の空のオブジェクトを適切な方法で作成できるようにします。 これはウェブサーバー用ではありません。 – JohnF

+0

しかし、最初にスレッドを何のために使用しようとしていますか? – duskwuff

答えて

3

スレッドがデータを適切に保存する唯一の方法は、新しいスレッドオブジェクトを作成してスレッドに送信することです。

はい、それを行う方法の1つです。

スレッドは、必要に応じて独自のストレージオブジェクトを作成できますか?

はい、ただし、そのスレッド内(または子スレッドが生成される可能性があります)で操作する場合のみです。

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のうち、別のスレッドで実行されるのはThread::runメソッドのみです)。

セッター注入を使用することもできます。 (ただし、セッターがThreadedオブジェクトが使用される最も外側の範囲にあるスレッドによって呼び出されている限り)。

PHPでスレッディングすることを初めて熟知している多くの開発者は、新しいスレッドの内部から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:pスレッドがすでに%Sで破壊されたオブジェクトに接続しようとする試みを検出した:%d

$thread->storeThreadedオブジェクトが、生成された子スレッドに参加するときに破棄されたためです。この問題ははるかに微妙なこともあります。たとえば、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:pスレッドがすでに%Sで破壊されたオブジェクトに接続しようとする試みを検出しました。 %d

あなたのサンプルコードに戻ってみると、あなたがやっていることは絶対にうまくいきますが、使用しようとしない限り$this->someDataはその子スレッドの外側にあります。

1

PHPのスレッドを使用しないでください。これらは基本的に役に立たず、理由は次のとおりです。

最初:Threads can only be used in the PHP CLI、スタンドアロンのコマンドラインスクリプトの場合。 PHP Webアプリケーションでは使用できません。 Webアプリケーションでは、複数のリクエストを一度に実行できるようにすることで同時実行性が得られます。

2番目:スレッドを使用すると、アプリケーションのすべて部分で広範かつ明示的なサポートが必要です。これは、Webサーバー環境で自然に発生します。 Threadedを拡張しないクラスは、スレッドアプリケーションでは使用できません。これにより、ほとんどのPHPクラスとフレームワークは使用できなくなります。実際、組み込みのPHPクラスでさえ、スレッドコードで安全に使用することはできません。

問題の長短は次のとおりです。PHP pthreads拡張は、それをサポートするようには決して設計されていない言語にスレッドを導入しようとする心がけの試みです。拡張子は非常に制限されており、使用するのにはぎこちなく、遅くなります。避けてください。

関連する問題