Qik Stream
-
PHP (pseudo)Threads
1 CommentBrakuje mi w PHP wielowątkowości. Jakoś autorom nie jest pilno do tego a czasem by się przydało.
Z potrzeby chwili powstało coś takiego:
class Thread { private $token=false; private $semaphore=false; private $data=array(); function __construct() { $data=array(); $SHM_KEY = ftok(__FILE__, chr( 4 ) ); $this->semaphore = sem_get($SHM_KEY,1); $this->token = shm_attach($SHM_KEY, 1024, 0666); @shm_remove($this->token); shm_attach($this->token); @shm_put_var($this->token,1,$data); } function __call($method,$params) { if(substr($method,0,3)==='___') { $pid=pcntl_fork(); if($pid) { $method=substr($method,3); @call_user_func_array(array(&$this,$method),$params); } } } function __sleep() { } function __wakeup() { } function __set($key,$value) { if(substr($key,0,3)==='___') { $key=substr($key,3); sem_acquire($this->semaphore); $data=@shm_get_var($this->token,1); $data[$key]=$value; @shm_put_var($this->token,1,$data); sem_release($this->semaphore); } $this->data[$key]=$value; return $value; } function __get($key) { if(substr($key,0,3)==='___') { $key=substr($key,3); $data=@shm_get_var($this->token,1); if(isset($data[$key])) { $ret=$data[$key]; $this->data[$key]=$ret; } else { $ret=$this->data[$key]; } } else { $ret=$this->data[$key]; } return $ret; } }
Korzysta się z tego dość prosto.
Przykład klasy wykorzystującej wątkowanie:class Thread_Test extends Thread { function loop1() { for($this->___i1=0;true;$this->___i1++) { sleep(3); } } function loop2() { for($this->i2=0;true;$this->i2++) { sleep(2); } } function loop3() { for($this->i3=0;true;$this->i3++) { echo "loop1: {$this->___i1} loop2: {$this->___i2} loop3: {$this->___i3} loop4: {$this->___i4}\n"; sleep(1); } } function loop4() { for($this->___i4=0;true;$this->___i4++) { } } }
i właściwe wywołanie:
$t = new Thread_Test(); $t->___loop1(); $t->___loop2(); $t->___loop4(); $t->loop3(); while(1) { sleep(1); echo "MAIN {$t->___i1} \n"; }
Jak widać ;P aby wywołać metodę jako osobny wątek dodajemy przed jej nazwą trzy znaki podkreślenia, np $t->___waitLongTime(); To samo tyczy się zmiennych. Zmienne zapisane tradycyjnie ($t->zmienna) są zmiennymi lokalnymi wątku, zmienne z trzema znakami podkreślenia ($t->___zmienna) są zmiennymi współdzielonymi w klasie, dostępnymi dla wszystkich wątków.
Dostęp do zmiennych współdzielonych jest bardzo wolny. Spowodowane jest to koniecznością synchronizowania zapisów do zmiennych.

Recent Comments