&reftitle.examples; Простые таймеры stop(); // Остановливаем наблюдателя, если следующий вызов приведёт к десятой (или больше) итерации Ev::iteration() >= 10 and $w->stop(); }); // Создаём остановленный таймер. Он будет неактивен, пока мы его не запустим $w_stopped = EvTimer::createStopped(10, 5, function($w) { echo "Callback-функция таймера, созданного остановленным\n"; // Останавливаем наблюдателя через 2 итерации Ev::iteration() >= 2 and $w->stop(); }); // Запускаем событийный цикл, пока работает хотя бы один наблюдатель или пока не вызван Ev::stop() Ev::run(); // Запускаем и смотрим, как он работает $w_stopped->start(); echo "Запускаем одну итерацию\n"; Ev::run(Ev::RUN_ONCE); echo "Перезапускаем второго наблюдателя и пытаемся отловить те же события, но не блокируем\n"; $w2->again(); Ev::run(Ev::RUN_NOWAIT); $w = new EvTimer(10, 0, function() {}); echo "Запускаем блокирующий цикл\n"; Ev::run(); echo "END\n"; ?> ]]> &example.outputs.similar; Периодический таймер. Срабатывает раз в 10.5 секунд ]]> Периодический таймер. Использование callback-функции для перезадания интервала ]]> Периодический таймер. Срабатывает каждые 10.5 секунд, начиная с текущего момента ]]> Ждём, пока STDIN не станет читаемым ]]> Используем асинхронный ввод/вывод для доступа к сокету stop(); // Останавливаем наблюдателя $write_watcher $w->stop(); $in = "HEAD / HTTP/1.1\r\n"; $in .= "Host: google.co.uk\r\n"; $in .= "Connection: Close\r\n\r\n"; if (!socket_write($socket, $in, strlen($in))) { trigger_error("Ошибка записи $in в сокет", E_USER_ERROR); } $read_watcher = new EvIo($socket, Ev::READ, function ($w, $re) use ($socket, $e_nonblocking) { // Сокет доступен для чтения. Читаем 20 байт в неблокирующем режиме $ret = socket_recv($socket, $out, 20, MSG_DONTWAIT); if ($ret) { echo $out; } elseif ($ret === 0) { // Все прочтено $w->stop(); socket_close($socket); return; } // Ловим EINPROGRESS, EAGAIN или EWOULDBLOCK if (in_array(socket_last_error(), $e_nonblocking)) { return; } $w->stop(); socket_close($socket); }); Ev::run(); }); $result = socket_connect($socket, $address, $service_port); Ev::run(); ?> ]]> &example.outputs.similar; Встраиваем один цикл в другой ]]> Встраивание цикла, созданного с помощью kqueue в цикл по умолчанию ]]> Перехватываем сигнал SIGTERM stop(); }); Ev::run(); ?> ]]> Отслеживаем изменение /var/log/messages attr(); if ($attr['nlink']) { printf("Текущий размер: %ld\n", $attr['size']); printf("Текущее значение atime: %ld\n", $attr['atime']); printf("Текущее значение mtime: %ld\n", $attr['mtime']); } else { fprintf(STDERR, "файл `messages` отсутствует!"); $w->stop(); } }); Ev::run(); ?> ]]> Отслеживаем изменение /var/log/messages. Избегаем пропуска обновлений с помощью задержки в одну секунду stop(); $stat = $w->data; // 1 секунду после последнего изменения файла printf("Текущий размер: %ld\n", $stat->attr()['size']); }); $stat = new EvStat("/var/log/messages", 0., function () use ($timer) { // Сбрасываем наблюдателя $timer $timer->again(); }); $timer->data = $stat; Ev::run(); ?> ]]> Отслеживаем изменения статуса процесса stop(); printf("Процесс %d вышел с кодом %d\n", $w->rpid, $w->rstatus); }); Ev::run(); // Защита от зомби процессов pcntl_wait($status); } else { // Порождённый потомок exit(2); } ?> ]]>