rootiteam / snooze
使用 pthreads 扩展的代码的线程通知管理库
0.4.2
2023-07-03 20:24 UTC
Requires
- php-64bit: ^8.1
- ext-pmmpthread: ^6.0
This package is auto-updated.
Last update: 2024-09-03 23:09:47 UTC
README
使用 pthreads 扩展的代码的事件驱动线程通知管理库
用例
ext-pthreads 目前不能方便地对来自多个线程的通知同时执行 wait()
。这个库允许您使用 SleeperHandler
来实现这一点。
每个线程必须接收自己的 SleeperNotifier
(由于它们是线程安全的,您可以在线程之间共享通知器,但推荐不要这样做)。线程应在其 SleeperNotifier
上调用 wakeupSleeper()
,这将导致在 SleeperHandler
上等待的线程被唤醒并处理传递的通知。
它与在数组套接字或文件描述符上使用 select()
系统调用类似,但使用的是线程。
示例
class SleepyThread extends \Thread{ /** @var \pocketmine\snooze\SleeperNotifier */ private $notifier; /** @var \Threaded */ private $buffer; public function __construct(\pocketmine\snooze\SleeperNotifier $notifier, \Threaded $buffer){ $this->notifier = $notifier; $this->buffer = $buffer; } public function run() : void{ $stdin = fopen('php://stdin', 'r'); while(true){ echo "Type something and press ENTER:\n"; //do whatever you're doing $line = fgets($stdin); //blocks until the user enters something //add the line to the buffer $this->buffer[] = $line; //send a notification to the main thread to tell it that we read a line //the parent thread doesn't have to be sleeping to receive this, it'll process it next time it tries to go //back to sleep //if the parent thread is sleeping, it'll be woken up to process notifications immediately. $this->notifier->wakeupSleeper(); } } } $sleeper = new \pocketmine\snooze\SleeperHandler(); $notifier = new \pocketmine\snooze\SleeperNotifier(); $buffer = new \Threaded(); $thread = new SleepyThread($notifier, $buffer); $sleeper->addNotifier($notifier, function() use($buffer) : void{ //do some things when this notifier sends a notification echo "Main thread got line: " . $buffer->shift(); }); //don't start the thread until we add the notifier, otherwise we could get unexpected behaviour (race conditions) $thread->start(); while(true){ $start = microtime(true); //do some work that you do every tick //process any pending notifications, then try to sleep 50ms until the next tick //this may wakeup at any time to process received notifications //if it wakes up and there is still time left to sleep before the specified time, it will go back to sleep again //until that time, guaranteeing a delay of at least this amount //if there are notifications waiting when this is called, they'll be processed before going to sleep $sleeper->sleepUntil($start + 0.05); } while(true){ //alternatively, if you want to only wait for notifications and not tick: //but from the pthreads rulebook, only ever wait FOR something! //this will wait indefinitely until something wakes it up, and then return immediately $sleeper->sleepUntilNotification(); }