Как реализовать таймер на php, работающий совместно со stream_select?

Есть код, который срабатывает когда приходит событие по одному из прослушиваемых сокетов.
while (true) {
    //формируем массив прослушиваемых сокетов:
    $read = $connects;
    
    stream_select($read, $write, $except, null);//ожидаем сокеты доступные для чтения (без таймаута)
        ...обрабатываем $read
}

Нужно также срабатывание по таймеру 20 раз в секунду.
Если для этого использовать таймаут:
stream_select($read, $write, $except, 0.05));
то процессор постоянно загружен на 100% (о чём и предупреждают на php.net, что stream_select с таймерами работает не эффективно)

Мою задачу можно легко решить используя libevent:
$this->base = event_base_new();
$timer = event_timer_new();
event_timer_set($timer, array($this, '_onTimer'), $timer);
event_base_set($timer, $this->base);
event_timer_add($timer);

Но мне нужно решить задачу без использования libevent.

Сейчас решаю задачу так: создаю парный сокет используя stream_socket_pair(), делаю fork() и в дочернем процессе в бесконечном цикле записываю данные в парный сокет $parent:
while (true) {
    fwrite('ping', $parent);
    usleep(50000);
}

В родительском же процессе прослушиваю парный сокет $child, который связан с дочерним:
$read = [$child];
Это позволяет мне добиться нужного эффекта с нулевой загрузкой процессора.

Есть ли какая-то возможность создавать сокеты, которые бы отваливались по таймауту, так чтобы срабатывала функция stream_select с этим событием, чтобы код был аналогично libevent?
Сразу предупрежу, что tick в данном случае не работает, по-тому что пока stream_select ждёт событий по прослушиваемым сокетам - "тиков" не происходит.
  • Вопрос задан
  • 5229 просмотров
Пригласить эксперта
Ответы на вопрос 1
@rowdyro
Есть расширение для пыха www.php.net/manual/en/class.thread.php, но я не в курсе его качества. Один поток блокирующее читает, другой делает нужные дела 20 раз в секунду.
Была аналогичная задача, с пыхом многопоточность не очень дружит, я написал прослойку на C++
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы