1.关于pthreads v3的更新说明
v3版本是对PHP7进行的调整,移除了很多v2的方法和类,下面是移除的内容
Mutex,Cond, and Stackable
Threaded::lock and Threaded::unlock
Threaded::isWaiting
Threaded::from
Thread::kill
Thread::detach
Worker::isWorking
Threaded::getTerminationInfo
更多内容详见:https://github.com/krakjoe/pthreads
2.使用互斥锁的原因
当多个线程之间有共享的数据时,如果没有锁机制,那么多个线程可能同时获取某一个值,或者同时写入某一个值,导致最后某个值重复的读取或写入,这里有点像mysql事务中的幻读现象。下面我们来重现这种现象。
<?php
class MyThread extends Thread
{
public function __construct()
{
$this->start();
}
public function run()
{
$val = file_get_contents('/tmp/info.txt');
echo "读取:" . $val . " tid:" . $this->getThreadId() .
date(" Y-m-d H:i:s", time()) . PHP_EOL;
echo "成功写入了". file_put_contents('/tmp/info.txt', ++$val) .
"字节值为:$val" . " tid:" . $this->getThreadId() .
date(" Y-m-d H:i:s", time()) . PHP_EOL;
}
}
file_put_contents('/tmp/info.txt', 0);
$threads = [];
for($i = 0; $i < 100; $i++) {
$threads[$i] = new MyThread();
}
for($i = 0; $i < 100; $i++) {
$threads[$i]->join();
}

3.如何使用互斥锁
pthreads v2有用到互斥量的方法来实现互斥锁,但是在v3中把互斥量等方法都干掉了。理由是:互斥量存在危险性可能产生死锁,可以用synchronized方法来代替。原文截图如下:

那么我们只能用synchronized的方法自己来实现一个互斥锁了,注意互斥锁本质也是 synchronized (同步)的一种。(补充:对于文件的写入追加独占锁,在多线程环境下对于并发的线程来说还是可以同时写入的,详见官方文档说明。)
<?php
class Mutex extends Threaded
{
public function __construct($status = false)
{
$this->lock = $status;
}
public function getLock()
{
return $this->lock;
}
public function setLock($status)
{
$this->lock = $status;
}
}
class MyThread extends Thread
{
public function __construct(Mutex $mutex)
{
$this->mutex = $mutex;
$this->start();
}
public function run()
{
$this->synchronized(function($mutex) {
if (!$mutex->getLock()) {
$mutex->setLock(true);
$val = file_get_contents('/tmp/info.txt');
echo "读取:" . $val . " tid:" .
$this->getThreadId() .
date(" Y-m-d H:i:s", time()) . PHP_EOL;
echo "成功写入了". file_put_contents('/tmp/info.txt', ++$val) .
"字节值为:$val" . " tid:" . $this->getThreadId() .
date(" Y-m-d H:i:s", time()) . PHP_EOL;
$mutex->setLock(false);
} else {
echo 'Can not write' . PHP_EOL;
}
},$this->mutex);
}
}
file_put_contents('/tmp/info.txt', 0);
$mutex = new Mutex();
$threads = [];
for($i = 0; $i < 100; $i++) {
$threads[$i] = new MyThread($mutex);
}
for($i = 0; $i < 100; $i++) {
$threads[$i]->join();
}
