<?php
/**
展示事件使用的示例。
文档目前还很薄弱,所以我不确定这个示例是否是最佳解决方案。但它确实有效。
*/
use parallel\{Channel,Runtime,Events,Events\Event};
$myThread = function(Channel $channel) {
$events = new Events();
$events->addChannel($channel);
//$events->setBlocking(false); //取消注释以不阻塞 Events::poll()
$events->setTimeout(1000000); //在不阻塞时注释
while(true)
{
/*
...
你的代码。
...
*/
//读取所有可用事件
try
{
$event = NULL;
do
{
$event = $events->poll(); //如果有事件则返回非空值
if($event && $event->source == 'myChannel')
{
//看起来,目标在返回事件后被删除,
//所以再次添加它。
$events->addChannel($channel);
if($event->type == Event\Type::Read)
{
if(is_array($event->value) && count($event->value) > 0)
{
if($event->value['name'] == 'stop')
{
echo 'Stopping thread';
return; //停止
}
else
{
echo 'Event: '.$event->value['name'].' => '.$event->value['value'].PHP_EOL;
}
}
}
else if($event->type == Event\Type::Close) return; //停止
}
}
while($event);
}
catch(Events\Error\Timeout $ex)
{
//超时
echo 'Timeout'.PHP_EOL;
}
}
};
class MyClass {
private $runtime;
private $future;
private $channel;
public function start() {
//创建运行时
$this->runtime = new Runtime();
//创建缓冲通道。
//缓冲通道不会阻塞 Channel::send()。
//注意,目标名称在进程中需要是唯一的。
$this->channel = Channel::make('myChannel', Channel::Infinite);
global $myThread;
$this->future = $this->runtime->run($myThread, [$this->channel]);
}
public function stop() {
$this->channel->send(['name' => 'stop', 'value' => true]);
$this->future->value(); //等待线程完成
$this->channel->close();
}
public function emit(string $name, $value)
{
$this->channel->send(['name' => $name, 'value' => $value]);
}
}
$a = new MyClass();
$a->start();
for($i = 0; $i < 5; $i++)
{
$a->emit('test', $i);
sleep(0.5);
}
sleep(2);
for($i = 5; $i < 10; $i++)
{
$a->emit('test', $i);
sleep(0.5);
}
$a->stop();
?>