如何在php中的线程之间共享全局变量? [英] How to share global variable across thread in php?

查看:2103
本文介绍了如何在php中的线程之间共享全局变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在多线程中,全局变量或资源在线程之间共享. 我在c中使用pthread库

In multithreading the global variables or resources are shared among threads. I'm using pthread library in c

#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 started\n", ctr);
    sleep(1);
//~ ctr += 1;
    printf("job %d finished\n", ctr);

//~ pthread_mutex_unlock(&lock);
}

此代码输出:

job 1 started
job 2 started
job 2 finished
job 2 finished

在此代码中,变量ctr在线程之间共享,因此,另一个线程可以看到其他线程对该变量所做的更改(除非已完成对某些mutexes的调用).

In this code the variable ctr are shared among thread, and therefore change made by other thread to that variable is visible to another thread (unless a call to some mutexes is done).

我在php中尝试过,但是没有运气(使用php pthreads). 这是我的php代码:

I'm tried that in php but no luck (using php pthreads). This is my php code :

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 ]

像上面的c代码一样,线程未更新变量ctr(全局)吗?

the variable ctr(global) not updated by the thread like the c code above?

如何在php中做到这一点(跨线程共享资源)?

How to do that in php (sharing resources across threads)?

推荐答案

通常,线程在与启动线程的进程相同的地址空间中执行.

Ordinarily, threads are executed in the same address space as the process that started them.

因此,在C语言中,新线程能够直接访问主程序堆栈上的变量.

So, in C, the new threads are able to directly access variables on the stack of the main program.

在PHP中创建新线程时,它具有单独的堆,它必须在单独的地址空间中执行.

When you create a new thread in PHP, it has a separate heap, it must execute in a separate address space.

这意味着默认情况下,您不能在线程之间共享全局状态.

This means that by default, you cannot share global state between threads.

这是PHP的普通线程模型-不共享.

This is the normal threading model of PHP - Share Nothing.

pthreads的作用是引入能够在许多上下文中进行操作并能够在这些上下文之间共享数据的对象.

What pthreads does is introduce objects which are able to be manipulated in many contexts, and are able to share data among those contexts.

等效的PHP代码可能类似于:

The equivalent PHP code might look something like:

<?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不能直接使用(已从最新版本的pthreads中删除).使用Mutex是危险的,因为您没有足够的执行控制权来安全地使用它们.如果您锁定了一个互斥锁,然后由于任何原因解释器遭受致命错误,则您将无法释放该互斥锁,死锁将随之而来...

Notice that, Mutex is not used directly (and has been removed from the latest versions of pthreads). Using Mutex is dangerous because you do not have enough control over execution to use them safely; If you lock a mutex and then for whatever reason the interpreter suffers a fatal error, you will not be able to release the mutex, deadlocks will follow ...

也没有必要,因为在对象范围内的单指令操作是原子的.

Nor is it necessary because single instruction operations on the object scope are atomic.

在实现排他性时,您可以使用Threaded::synchronized API发挥巨大作用.

When it comes to implementing exclusion, you can use the Threaded::synchronized API to great effect.

在需要排除的地方,run方法可能更像:

Where exclusion is required, the run method might look more like:

    public function run() {
        $this->atomic->synchronized(function($atomic){
            /* exclusive */
            $atomic->inc();
        }, $this->atomic);
    }

最后,一个关于事物命名的课程...

Finally, a lesson in naming things ...

您似乎已经被宽容,因为您对Posix线程(标准,pthread)和pthread(PHP扩展)之间存在一些相似之处感到宽恕.

You appear to be, and are forgiven for being under the impression that, there is some parallel to be drawn between Posix Threads (the standard, pthread) and pthreads, the PHP extension ...

pthreads,PHP扩展恰好是 use 使用Posix线程,但它没有 implement 类似于Posix Threads.

pthreads, the PHP extension happens to use Posix Threads, but it doesn't implement anything like Posix Threads.

名称pthreads应该用来表示PHP线程...很难命名.

The name pthreads should be taken to mean PHP threads ... naming things is hard.

这篇关于如何在php中的线程之间共享全局变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆