如何在php中跨线程共享全局变量?
在多线程中,全局变量或资源在线程之间共享.
我在c中使用pthread库 #include <stdio.h> #include <pthread.h> #include <unistd.h> void *worker(void *); int ctr = 0; pthread_mutex_t lock; int main(int argc,char *argv[]) { pthread_t t[2]; int i = 0; //~ pthread_mutex_init(&lock,NULL); while(i < 2) { pthread_create(&t[i],NULL,&worker,NULL); i++; } pthread_join(t[0],NULL); pthread_join(t[1],NULL); //~ pthread_mutex_destroy(&lock); //~ pthread_join(t[1],NULL); return 0; } void *worker(void *arg) { //~ pthread_mutex_lock(&lock); //~ int ctr = 0; ctr += 1; printf("job %d startedn",ctr); sleep(1); //~ ctr += 1; printf("job %d finishedn",ctr); //~ pthread_mutex_unlock(&lock); } 此代码输出: job 1 started job 2 started job 2 finished job 2 finished 在此代码中,变量ctr在线程之间共享,因此其他线程对该变量所做的更改对另一个线程是可见的(除非完成对某些互斥锁的调用). 我在php中试过但没有运气(使用php pthreads). global $ctr; Class WorkerThread extends Worker { private $thread_id; //~ public static $ctr = 0; private $mutext; public function WorkerThread($mutex = NULL) { //~ $this->ctr = $ctr; $this->mutex = $mutex; $this->start(); } public function run() { //~ Mutex::lock($this->mutex); $new_line = php_sapi_name() == "cli" ? PHP_EOL : "<br>"; //~ global $ctr; $ctr = 0; $ctr += 1; echo "Thread " . $ctr . " started" . " [ " . $this->getThreadId() . " ]" . $new_line; sleep(1); echo "Thread " . $ctr . " Finished" . " [ " . $this->getThreadId() . " ]" . $new_line; //~ var_dump($this); //~ Mutex::unlock($this->mutex); } } //~ $mutex = Mutex::create(); $i = 0; $worker = array(); while($i < 2) { $worker[$i] = new WorkerThread(); //~ $worker[$i]->start(); $i++; } foreach(range(0,1) as $t) $worker[$t]->join(); //~ Mutex::destroy($mutex); 输出此代码: Thread 1 started [ -1257948352 ] Thread 1 started [ -1267893440 ] Thread 1 Finished [ -1257948352 ] Thread 1 Finished [ -1267893440 ] 变量ctr(全局)没有像上面的c代码一样被线程更新? 如何在PHP(跨线程共享资源)中做到这一点? 解决方法
通常,线程在与启动它们的进程相同的地址空间中执行.
因此,在C中,新线程能够直接访问主程序堆栈上的变量. 在PHP中创建新线程时,它有一个单独的堆,它必须在单独的地址空间中执行. 这意味着默认情况下,您无法在线程之间共享全局状态. 这是PHP的正常线程模型 – 无共享. pthreads所做的是引入能够在许多上下文中操作的对象,并且能够在这些上下文之间共享数据. 等效的PHP代码可能类似于: <?php class Atomic extends Threaded { public function __construct($value = 0) { $this->value = $value; } public function inc() { return $this->value++; } /* ... */ private $value; } class Test extends Thread { public function __construct(Atomic $atomic) { $this->atomic = $atomic; } public function run() { $this->atomic->inc(); } private $atomic; } $atomic = new Atomic(); $threads = []; for ($thread = 0; $thread < 2; $thread++) { $threads[$thread] = new Test($atomic); $threads[$thread]->start(); } foreach ($threads as $thread) $thread->join(); var_dump($atomic); ?> 请注意,Mutex不是直接使用的(并且已从最新版本的pthread中删除).使用Mutex是危险的,因为您没有足够的执行控制来安全地使用它们;如果您锁定互斥锁然后由于某种原因解释器遭受致命错误,您将无法释放互斥锁,死锁将跟随… 也没有必要,因为对象范围上的单个指令操作是原子的. 在实现排除时,您可以使用Threaded :: synchronized API获得很好的效果. 如果需要排除,run方法可能看起来更像: public function run() { $this->atomic->synchronized(function($atomic){ /* exclusive */ $atomic->inc(); },$this->atomic); } 最后,给命名事项的一课… 你似乎是,并且被认为是在Posix线程(标准,pthread)和pthreads之间有一些平行,PHP扩展… pthreads,PHP扩展恰好使用Posix Threads,但它没有实现像Posix Threads这样的东西. pthreads这个名字应该被理解为PHP线程…命名很难. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |