Различия
Показаны различия между двумя версиями страницы.
| Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
| php:pthreads [2017/01/23 21:08] – [Threading for PHP - Share Nothing] mirocow | php:pthreads [2017/01/25 00:46] (текущий) – [Статьи] mirocow | ||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| - | ====== Threading for PHP - Share Nothing ====== | + | {{tag> |
| + | |||
| + | ====== | ||
| * https:// | * https:// | ||
| Строка 5: | Строка 7: | ||
| * https:// | * https:// | ||
| + | ===== Установка ===== | ||
| + | |||
| + | ==== Brew (MacOS) ==== | ||
| + | |||
| + | <code bash> | ||
| + | $ brew install php70-pthreads | ||
| + | </ | ||
| + | |||
| + | ==== pecl ==== | ||
| + | |||
| + | <code bash> | ||
| + | $ pecl install pthread | ||
| + | </ | ||
| + | |||
| + | ==== Docker ==== | ||
| + | |||
| + | <code bash> | ||
| + | $ docker pull jdecool/ | ||
| + | </ | ||
| ===== Примеры ===== | ===== Примеры ===== | ||
| Строка 27: | Строка 48: | ||
| $pool-> | $pool-> | ||
| </ | </ | ||
| + | |||
| + | <code php> | ||
| + | <?php | ||
| + | |||
| + | function demanding(...$params) { | ||
| + | /* you have parameters here */ | ||
| + | return array(rand(), | ||
| + | } | ||
| + | |||
| + | class Task extends Collectable { | ||
| + | public function __construct(Threaded $result, $params) { | ||
| + | $this-> | ||
| + | $this-> | ||
| + | } | ||
| + | |||
| + | public function run() { | ||
| + | $this-> | ||
| + | demanding(...$this-> | ||
| + | } | ||
| + | |||
| + | protected $result; | ||
| + | protected $params; | ||
| + | } | ||
| + | |||
| + | $pool = new Pool(16); | ||
| + | |||
| + | $result = new Threaded(); | ||
| + | |||
| + | while (@$i++< | ||
| + | $pool-> | ||
| + | new Task($result, | ||
| + | } | ||
| + | |||
| + | $pool-> | ||
| + | |||
| + | var_dump($result); | ||
| + | ?> | ||
| + | </ | ||
| + | |||
| + | <code php> | ||
| + | class Scanner { | ||
| + | public function performScan() { | ||
| + | // Add initial task | ||
| + | $initialTask = "Task 1"; | ||
| + | TaskQueue:: | ||
| + | |||
| + | $i = 0; | ||
| + | while(true) { | ||
| + | // Get task from queue | ||
| + | $task = TaskQueue:: | ||
| + | if ($task == null) | ||
| + | | ||
| + | |||
| + | // Handle task | ||
| + | $parser[$i] = new Parser($task); | ||
| + | $parser[$i]-> | ||
| + | |||
| + | // Wait | ||
| + | $thread = $parser[$i]; | ||
| + | $thread-> | ||
| + | while (!$thread-> | ||
| + | $thread-> | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | // Join | ||
| + | $i++; | ||
| + | } | ||
| + | |||
| + | // Done | ||
| + | echo " | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class Parser extends Thread { | ||
| + | private $task; | ||
| + | |||
| + | public function __construct($task) { | ||
| + | $this-> | ||
| + | } | ||
| + | |||
| + | public function run() { | ||
| + | // Perform a time-consuming operation | ||
| + | // This operation adds an unknown number of extra tasks | ||
| + | sleep(1); | ||
| + | |||
| + | // Add new tasks to queue | ||
| + | foreach(range(0, | ||
| + | TaskQueue:: | ||
| + | } | ||
| + | |||
| + | // Notify | ||
| + | $this-> | ||
| + | $this-> | ||
| + | $this-> | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class TaskQueue { | ||
| + | private static $queue = array(); | ||
| + | |||
| + | public static function addTask($task) { | ||
| + | self:: | ||
| + | echo "Add task to queue!\n"; | ||
| + | } | ||
| + | |||
| + | public static function getTask() { | ||
| + | if (sizeof(self:: | ||
| + | $task = array_shift(self:: | ||
| + | echo "Get task from queue!\n"; | ||
| + | return $task; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | $scanner = new Scanner(); | ||
| + | $scanner-> | ||
| + | </ | ||
| + | |||
| + | <code php> | ||
| + | <?php | ||
| + | class Referee extends Threaded { | ||
| + | |||
| + | public function find(string $ident, Threaded $reference) { | ||
| + | return $this-> | ||
| + | if (isset($this[$ident])) { | ||
| + | return $this[$ident]; | ||
| + | } else return ($this[$ident] = $reference); | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | public function foreach(Closure $closure) { | ||
| + | $this-> | ||
| + | foreach ($this as $ident => $reference) { | ||
| + | $closure($ident, | ||
| + | } | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | class Test extends Thread { | ||
| + | |||
| + | public function __construct(Referee $referee, string $ident, bool $delay) { | ||
| + | $this-> | ||
| + | $this-> | ||
| + | $this-> | ||
| + | } | ||
| + | |||
| + | public function run() { | ||
| + | while (1) { | ||
| + | if ($this-> | ||
| + | $this-> | ||
| + | $this-> | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | $reference = | ||
| + | $this-> | ||
| + | |||
| + | /* do something with reference here, I guess */ | ||
| + | |||
| + | /* do something with all references here */ | ||
| + | $this-> | ||
| + | var_dump(Thread:: | ||
| + | $reference-> | ||
| + | $reference-> | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | public function getIdent() { | ||
| + | return $this-> | ||
| + | } | ||
| + | |||
| + | private $referee; | ||
| + | private $ident; | ||
| + | private $delay; | ||
| + | } | ||
| + | |||
| + | $referee = new Referee(); | ||
| + | $threads = []; | ||
| + | $thread = 0; | ||
| + | $idents = [ | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ]; | ||
| + | |||
| + | while ($thread < 8) { | ||
| + | $threads[$thread] = new Test($referee, | ||
| + | $threads[$thread]-> | ||
| + | $thread++; | ||
| + | } | ||
| + | |||
| + | foreach ($threads as $thread) | ||
| + | $thread-> | ||
| + | ?> | ||
| + | </ | ||
| + | |||
| + | <code php> | ||
| + | class Wallet{ | ||
| + | public $balance; | ||
| + | public function __construct($money){ | ||
| + | $this-> | ||
| + | } | ||
| + | public function getBalance(){ | ||
| + | return $this-> | ||
| + | } | ||
| + | public function setBalance($value){ | ||
| + | $this-> | ||
| + | } | ||
| + | } | ||
| + | class MyThread extends Thread{ | ||
| + | private $wallet; | ||
| + | private $std; | ||
| + | public function __construct($wallet, | ||
| + | $this-> | ||
| + | $this-> | ||
| + | } | ||
| + | public function run(){ | ||
| + | $this-> | ||
| + | $hack = $this-> | ||
| + | if($hack-> | ||
| + | sleep(1); | ||
| + | $hack-> | ||
| + | echo $this-> | ||
| + | //Here is Wrong! | ||
| + | var_dump($hack == $this-> | ||
| + | } | ||
| + | else | ||
| + | echo $this-> | ||
| + | | ||
| + | }, | ||
| + | } | ||
| + | } | ||
| + | $wallet = new Wallet(200); | ||
| + | $std = new stdClass(); | ||
| + | for($x=0; | ||
| + | $pool[] = new MyThread($wallet, | ||
| + | $pool[$x]-> | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Примеры использования / Помошники (IDE Helpers) ===== | ||
| + | |||
| + | * https:// | ||
| + | * https:// | ||
| + | * https:// | ||
| + | ===== Документация ===== | ||
| + | |||
| + | * http:// | ||
| + | |||
| + | ===== Статьи ===== | ||
| + | |||
| + | * https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * http:// | ||
| + | * https:// | ||