本文實例講述了PHP pthreads v3使用中的一些坑和注意點。分享給大家供大家參考,具體如下:
一、子線程無法訪問父線程的全局變量,但父線程可以訪問子線程的變量
?php
class Task extends Thread
{
public $data;
public function run()
{
global $num;
var_dump($num);
$this->data = 'abc';
//這是打印null
var_dump($GLOBALS);
$GLOBALS['test'] = 'def';
}
}
//主線程中的全局變量,子線程中是無法訪問的
//php中創(chuàng)建子線程,它會有一個單獨的堆,運行在單獨的地址空間中
//并不能像有些語言中,子線程是可以訪問的到主線程中的變量的。
$num = 666;
$GLOBALS['test'] = 'test';
$t = new Task();
$t->start() $t->join();
//主線程可以訪問子線程的變量
var_dump($t->data);
結果如下:
二、子線程無法修改父線程的變量
?php
class Task extends Thread
{
private $data;
public function __construct($data)
{
$this->data = $data;
}
public function run()
{
echo "task data : ", $this->data, "\n";
$this->data = 'def';
echo "task data : ", $this->data, "\n";
}
}
$data = 'abc';
//我們這里傳入的是引用
$t = new Task($data);
$t->start() $t->join();
//但是$data變量數據并沒改變
//這說明我們通過構造函數傳入Task對象中的$data只是一個拷貝
//子線程中并不能夠操作主線程中的變量
var_dump($data);
結果如下:
三、pthreads v3版本可以設置成員為匿名函數
?php
class Task extends Thread
{
private $call;
public function __construct()
{
//pthreads v3版本好像可以設置成員為匿名函數
//在v2版本中好像是不可以的
$this->call = function ($param1, $param2) {
echo "task call param1 : {$param1} param2 : {$param2}\n";
};
}
public function run()
{
//直接調用成員匿名函數
($this->call)("hello", "world");
}
}
$t = new Task();
$t->start() $t->join();
結果如下:
四、對于數據庫連接資源,我們需要聲明為靜態(tài)成員
?php
class Task extends Thread
{
private $db;
public function __construct()
{
//注意這里會報錯,不能對PDO實例進行序列化或反序列化
$this->db = new PDO('mysql:dbname=test;host=192.168.33.226', 'root', '');
}
public function run()
{
$result = $this->db->query("select id,name from tb_user");
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
echo "{$row['id']}\t{$row['name']}\n";
}
}
}
$t = new Task();
$t->start() $t->join();
結果如下:
代碼修改如下:
?php
class Task extends Thread
{
//我們需要把數據庫連接資源,聲明為靜態(tài)成員,然后調用靜態(tài)方法進行創(chuàng)建
private static $db;
//我們直接在__construct()構造函數里對$db進行實例化,好像會是null,有興趣的可以試試
public static function getConn()
{
if (!is_resource(self::$db)) {
self::$db = new PDO('mysql:dbname=test;host=192.168.33.226', 'root', '');
}
return self::$db;
}
public function run()
{
$result = self::getConn()->query("select id,name from tb_user");
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
echo "{$row['id']}\t{$row['name']}\n";
}
}
}
$t = new Task();
$t->start() $t->join();
結果如下:
最后說明,不排除pthreads以后的版本升級上面的有些問題不會出現。
我的php版本是7.2.4,pthreads的版本是3.1.7dev
更多關于PHP相關內容感興趣的讀者可查看本站專題:《PHP進程與線程操作技巧總結》、《PHP網絡編程技巧總結》、《PHP基本語法入門教程》、《PHP數組(Array)操作技巧大全》、《php字符串(string)用法總結》、《php+mysql數據庫操作入門教程》及《php常見數據庫操作技巧匯總》
希望本文所述對大家PHP程序設計有所幫助。
您可能感興趣的文章:- PHP pthread拓展使用和注意點
- PHP pthreads v3下worker和pool的使用方法示例
- PHP pthreads v3下同步處理synchronized用法示例
- php使用pthreads v3多線程實現抓取新浪新聞信息操作示例
- PHP中使用pthread拓展