Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
php:pthreads [2017/01/24 17:12] – [Примеры] mirocowphp:pthreads [2017/01/25 00:46] (текущий) – [Статьи] mirocow
Строка 1: Строка 1:
 {{tag>php languages extension}} {{tag>php languages extension}}
  
-====== Threading for PHP - Share Nothing ======+====== Pthread (Threading for PHP - Share Nothing======
  
   * https://github.com/krakjoe/pthreads ([[https://github.com/krakjoe/pthreads/tree/PHP5|5.x]] - [[https://github.com/krakjoe/pthreads|7.x]])   * https://github.com/krakjoe/pthreads ([[https://github.com/krakjoe/pthreads/tree/PHP5|5.x]] - [[https://github.com/krakjoe/pthreads|7.x]])
Строка 7: Строка 7:
   * https://github.com/krakjoe/pthreads-polyfill   * https://github.com/krakjoe/pthreads-polyfill
  
 +===== Установка =====
 +
 +==== Brew (MacOS) ====
 +
 +<code bash>
 +$ brew install php70-pthreads
 +</code>
 +
 +==== pecl ====
 +
 +<code bash>
 +$ pecl install pthread
 +</code>
 +
 +==== Docker ====
 +
 +<code bash>
 +$ docker pull jdecool/php-pthreads
 +</code>
 ===== Примеры ===== ===== Примеры =====
  
Строка 148: Строка 167:
 $scanner->performScan(); $scanner->performScan();
 </code> </code>
 +
 +<code php>
 +<?php
 +class Referee extends Threaded {
 +
 +    public function find(string $ident, Threaded $reference) {
 +        return $this->synchronized(function () use($ident, $reference) {
 +            if (isset($this[$ident])) {
 +                return $this[$ident];
 +            } else return ($this[$ident] = $reference);
 +        });
 +    }
 +
 +    public function foreach(Closure $closure) {
 +        $this->synchronized(function() use($closure) {
 +            foreach ($this as $ident => $reference) {
 +                $closure($ident, $reference);
 +            }
 +        });
 +    }
 +}
 +
 +class Test extends Thread {
 +
 +    public function __construct(Referee $referee, string $ident, bool $delay) {
 +        $this->referee = $referee;
 +        $this->ident   = $ident;
 +        $this->delay   = $delay;
 +    }
 +
 +    public function run() {
 +        while (1) {
 +            if ($this->delay) {
 +                $this->synchronized(function(){
 +                    $this->wait(1000000);
 +                });
 +            }
 +
 +            $reference = 
 +                $this->referee->find($this->ident, $this);
 +
 +            /* do something with reference here, I guess */         
 +
 +            /* do something with all references here */
 +            $this->referee->foreach(function($ident, $reference){
 +                var_dump(Thread::getCurrentThreadId(),
 +                        $reference->getIdent(), 
 +                        $reference->isRunning());
 +            });
 +        }
 +    }
 +
 +    public function getIdent() {
 +        return $this->ident;
 +    }
 +
 +    private $referee;
 +    private $ident;
 +    private $delay;
 +}
 +
 +$referee = new Referee();
 +$threads = [];
 +$thread = 0;
 +$idents = [
 +    "smelly",
 +    "dopey",
 +    "bashful",
 +    "grumpy",
 +    "sneezy",
 +    "sleepy",
 +    "happy",
 +    "naughty"
 +];
 +
 +while ($thread < 8) {
 +    $threads[$thread] = new Test($referee, $idents[$thread], rand(0, 1));
 +    $threads[$thread]->start();
 +    $thread++;
 +}
 +
 +foreach ($threads as $thread)
 +    $thread->join();
 +?>
 +</code>
 +
 +<code php>
 +class Wallet{
 +    public $balance;
 +    public function __construct($money){
 +        $this->balance = $money;
 +    }
 +    public function getBalance(){
 +        return $this->balance;
 +    }
 +    public function setBalance($value){
 +        $this->balance = $value;
 +    }
 +}
 +class MyThread extends Thread{
 +    private $wallet;
 +    private $std;
 +    public function __construct($wallet,$std){
 +        $this->wallet = $wallet;
 +        $this->std = $std;
 +    }
 +    public function run(){
 +        $this->synchronized(function($thread){
 +                $hack = $this->wallet;
 +                if($hack->getBalance() - 80 >0){
 +                    sleep(1);
 +                    $hack->setBalance($hack->getBalance() - 80);
 +                    echo $this->getThreadId() . "reduce 80 successful<br/>Current num is:" . $hack->getBalance() . "<Br/>";
 +                    //Here is Wrong!  The result is bool(false)????!!!!
 +                    var_dump($hack == $this->wallet);
 +                }
 +                 else
 +                     echo $this->getThreadId() . "reduce fail<br/>Current num is:" . $hack->getBalance() . "<br/>";
 +            
 +        },$this->std);
 +    }
 +}
 +$wallet = new Wallet(200);
 +$std = new stdClass();
 +for($x=0;$x<3;$x++){
 +    $pool[] = new MyThread($wallet,$std);
 +    $pool[$x]->start();
 +}
 +</code>
 +
 +===== Примеры использования / Помошники (IDE Helpers) =====
 +
 +  * https://github.com/zerustech/pthreads-tutorial
 +  * https://github.com/unusorin/pthreads (IDE support for pthreads)
 +  * https://github.com/krakjoe/promises
 ===== Документация ===== ===== Документация =====
  
Строка 156: Строка 310:
   * https://habrahabr.ru/post/300952/   * https://habrahabr.ru/post/300952/
   * [[https://habrahabr.ru/post/193270/|PHP IPC — Межпроцессное взаимодействие в PHP]]   * [[https://habrahabr.ru/post/193270/|PHP IPC — Межпроцессное взаимодействие в PHP]]
 +  * [[https://habrahabr.ru/post/75454/|Почти настоящая многопоточность средствами php 5]]
 +  * http://www.smddzcy.com/2016/01/tutorial-multi-threading-in-php7-pthreads/
 +  * https://blog.madewithlove.be/post/thread-carefully/