1.什么是线程同步
线程同步就是指线程按照先后顺序对内存进行操作,以避免多个线程同时操作内存的情况。
2.线程同步的实现方法有哪些
1.临界区、2.互斥量、3.信号量、4.事件对象
3.PHP多线程中同步的实现方式
v3的同步主要用synchronized方法,昨天的 PHP多线程pthreads-v3-互斥锁的使用 就是用了 synchronized 写了一个互斥量的例子,互斥量对于不满足条件的线程没有做到阻塞等待,所以该线程也就没能执行它的任务。今天我们通过wait和notfiy来实现线程阻塞等待到通知同步的过程。
4.例子简介
首先对于继承自threaded的类,其成员变量如果是数组类型,实质会转换成Volatile对象。 (注意点)

我们的例子是按奇偶顺序初始化100个线程,奇数是UI线程,偶数是Worker线程。UI线程进行渲染操作的前提条件就是对应的Worker线程需要处理完数据才能执行。于是UI线程对于没有处理完的Worker线程会阻塞,直到Woker线程处理完数据后notify(通知)唤醒相应的UI线程进行渲染操作。
<?php
class ShareData extends Threaded
{
private $tids = [];
private $tids_reverse = [];
private $finish = [];
public function __construct()
{
}
public function pushTid($perfix, $tid)
{
$this->tids[$tid] = $perfix;
$this->tids_reverse[$perfix] = $tid;
$this->finish[$tid] = false;
}
public function getTidsLength()
{
return count($this->tids);
}
public function setStatusByTid($tid, $status)
{
$this->finish[$tid] = $status;
}
public function getTids($reverse = false)
{
return !$reverse ? $this->tids : $this->tids_reverse;
}
public function getStatusByPrefix($perfix)
{
return $this->finish[$this->tids_reverse[$perfix]];
}
public function getPrefixByTid($tid)
{
return $this->tids[$tid];
}
}
class MyThread extends Thread
{
public function __construct(ShareData $data)
{
$this->data = $data;
$this->start();
}
public function run()
{
$i = $this->data->getTidsLength();
$prefix = ($i % 2 == 0 ? 'work' : 'ui') . $i;
$tid = $this->getThreadId();
$this->data->pushTid($prefix, $tid);
$this->data->getTids()[$tid];
$this->synchronized(function ($thread, $prefix, $tid) {
if (strpos($prefix, 'ui') !== false) {
$id = ((int)substr($prefix, 2)) - 1;
$woker = 'work' . $id;
while (!$thread->data->getStatusByPrefix($woker)) {
echo '开始阻塞' . $this->data->getPrefixByTid($tid) . PHP_EOL;
sleep(1);
$thread->wait();
echo '开始执行' . $this->data->getPrefixByTid($tid) . PHP_EOL;
}
} else {
echo '开始执行' . $thread->data->getPrefixByTid($tid) . PHP_EOL;
sleep(4);
echo '执行完毕' . $thread->data->getPrefixByTid($tid) . PHP_EOL;
$thread->data->setStatusByTid($tid, true);
$thread->notify();
}
}, $this, $prefix, $tid);
}
}
$shareData = new ShareData();
for ($i = 0; $i < 100; $i++) {
$threads[$i] = new MyThread($shareData);
}
for ($i = 0; $i < 100; $i++) {
$threads[$i]->join();
}


