php多线程-传入数据到线程中

提到php多线程,网上的例子基本都是并发发起http请求,难道php多线程就只能干这个吗,搞笑。
于是,我写了一个使用多线程对100万个数的排序,在测试的过程中发现了几个问题,记录一下。

php多线程只有在实例化的时候有机会传入参数,于是,当我传入数组的时候,发现有点不对劲。

class Test extends Thread{
	public $data;
	public $response;

	public function __construct($fruit){
        var_dump($fruit);
		$this->data = $fruit;
        var_dump($this->data);
	}

	public function run(){
        
	}
}


$fruit = ['apple', 'balana', 'orange'];

$p = new Test($fruit);
$p->start();

var_dump($p); // 为了查看线程是否还在,如果线程内有错误的话,线程就会被 destroy

结果:

array(3) {
  [0]=>
  string(5) "apple"
  [1]=>
  string(6) "balana"
  [2]=>
  string(6) "orange"
}
object(Volatile)#2 (3) {
  [0]=>
  string(5) "apple"
  [1]=>
  string(6) "balana"
  [2]=>
  string(6) "orange"
}
object(Test)#1 (2) {
  ["data"]=>
  object(Volatile)#2 (3) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "balana"
    [2]=>
    string(6) "orange"
  }
  ["response"]=>
  NULL
}

也就是说,在构造函数中,我传入数组,给属性赋值的时候,就变成了 Volatile 对象。
关于 Volatile 对象,查看官方文档:https://php.net/manual/en/class.volatile.php

2、修改run()方法

public function run(){

    $this->response = $this->data;

}

结果:报错
也就说,只有构造函数中初始化的属性才配用上 Volatile 对象 。。。。。。

3、修改run()方法

public function run(){

    $this->data= null;

}

结果:报错
PHP Fatal error: Uncaught RuntimeException: Threaded members previously set
to Threaded objects are immutable, cannot overwrite data

也就说,构造函数中初始化的属性还不能改动它。。。。。。。。。

4、修改run()方法

public function run(){

    $this->response = (array)$this->data;
    var_dump($this->response);

}

结果:可行

array(3) {
  [0]=>
  string(5) "apple"
  [1]=>
  string(6) "balana"
  [2]=>
  string(6) "orange"
}
object(Test)#1 (2) {
  ["data"]=>
  object(Volatile)#2 (3) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "balana"
    [2]=>
    string(6) "orange"
  }
  ["response"]=>
  array(3) {
    [0]=>
    string(5) "apple"
    [1]=>
    string(6) "balana"
    [2]=>
    string(6) "orange"
  }
}

对于 Volatile 对象 ,懒得去研究,直接转数组就可以操作了啊。

5、修改run()方法

public function run(){
    $data = (array)$this->data;

    $data[5] = 55;

    $this->response = $data;
}

结果:报错,线程已终止
这就很无语了,莫名其妙嘛,于是尝试这 t h i s − > r e s p o n s e = ( a r r a y ) this->response = (array) this>response=(array)data;
尼玛,这样可以,呵呵,没搞懂。

注意点:
1.线程类的属性不能直接进行哈希表(数组)操作,如:

//这样是无效的
$this->var1["hello"] = "world"; 
//改为
$this->var1 = ["hello"=>"world"];

因为线程类属性的赋值是通过序列化实现的,其本质是存储了序列化数据,因此不支持PHP常用直接操作哈希表(数组)的操作

2.线程类的属性不能是“闭包函数”
原因:闭包函数不能序列化;因此,如果想在线程里用“回调函数”的话,那就放弃线程吧;

3.线程对象开辟了php的第二空间
线程在创建之后,无法访问到父线程的变量,诸如$GLOBALS或global等用法都无法操作父线程的全局变量,这应该是考虑到了线程安全的问题;
但是父线程却能够访问子线程对象的内容;

4、传递数据库实例到线程里是无效的
传递进来的对象是好的,就是却无法执行数据库操作。建议还是在线程里去实例化数据库连接吧。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值