我在使用php pthreads for Windows從全局上下文訪問資源時遇到問題。pthreads在PHP中訪問全局資源
的邏輯非常簡單:有一個服務器作爲主類,只有一個,這將:
- 創建日誌文件
- 創建幾個線程
- 每個線程都需要寫的東西此日誌文件
問題是,日誌文件句柄的資源在某種程度上完全從線程內部搞砸了。當我創建資源時,沒關係,我可以寫入它。當我嘗試從正在運行的線程中調用日誌時,日誌文件處理程序的資源看起來是整數0,甚至不是資源。
這裏是我的代碼:
$main_server = new CMainServer();
$main_server->init();
$main_server->go();
$main_server->log("All done");
裏面的CMainServer類:
class CMainServer
{
private $logfile = null;
public function init()
{
$this->logfile = fopen('wstext.log', 'w');
}
public function log($str)
{
if ($this->logfile === null)
{
echo "[".date("H:i:s", time())."]: logfile is null<BR />";
return false;
}
if (!is_resource($this->logfile))
{
echo "[".date("H:i:s", time())."]: logfile is NOT a resource, can't write {$str}<BR />";
return false;
}
echo "[".date("H:i:s", time())."]: logfile is resource, not null, writing {$str}<BR />";
flush();
fwrite($this->logfile, "[".date("H:i:s", time())."]: {$str}\r\n");
return true;
}
public function go()
{
$this->log('Before creating a thread');
$first_thread = new CThread();
$first_thread->start(PTHREADS_INHERIT_ALL | PTHREADS_ALLOW_GLOBALS);
$second_thread = new CThread();
$second_thread->start(PTHREADS_INHERIT_ALL | PTHREADS_ALLOW_GLOBALS);
$first_thread->join();
$second_thread->join();
}
public function __destruct()
{
if ($this->logfile)
fclose($this->logfile);
}
}
最後,在CThread類:
class CThread extends Thread
{
public function run()
{
global $main_server;
$thread_id = $this->getThreadId();
Thread::globally(function()
{
for ($i = 0; $i < 2; $i++)
{
$main_server->log("({$i}) writing random number ".rand(0, 100)." to log from running thread id={$thread_id}");
sleep(1);
}
});
}
}
結果是可悲的:
[13:38:10]: logfile is NOT a resource, can't write (0) writing random number 21 to log from running thread id=9080
[13:38:11]: logfile is NOT a resource, can't write (1) writing random number 91 to log from running thread id=9080
[13:38:10]: logfile is NOT a resource, can't write (0) writing random number 16 to log from running thread id=17316
[13:38:11]: logfile is NOT a resource, can't write (1) writing random number 50 to log from running thread id=17316
[13:38:10]: logfile is resource, not null, writing Before creating a thread
[13:38:12]: logfile is resource, not null, writing All done
所以,雖然我在線外,一切都很好。但是,從一個線程內,$ logfile根本就不是資源。
我嘗試了不同的選擇:從CThread打過電話:: run()的全局函數:
function LogFromThread($i, $thread_id)
{
global $main_server;
$main_server->log("({$i}) writing random number ".rand(0, 100)." to log from running thread id={$thread_id}");
}
的結果是一樣的。
沒有線程::全局()的嘗試,但都沒有好處。
我正在運行Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.6.3
,試過pthreads版本2.0.8,2.0.9。也嘗試過用PHP 7RC2和RC3,但似乎有一個問題開始一個新的線程,apache記錄一個錯誤,所以我回到了5.6.3。
也許有人可以給我一個這方面的提示嗎?
非常感謝! =)