如何使用PHP中pcntl和libevent實現Timer功能
PHP 中實作Timer功能,中間使用到了php多線程,本文給出來pcntl的解釋。
PHP 使用pcntl和libevent 實作Timer功能,先看例子,pcntl(PHP執行緒)解釋在下面。
<?php function newChild($func_name) { echo "enter newChild\n"; $args = func_get_args(); unset($args[0]); $pid = pcntl_fork(); if ($pid == 0) { function_exists($func_name) and exit(call_user_func_array($func_name, $args)) or exit(-1); } else if($pid == -1) { echo "Couldn't create child process"; } else { return $pid; } } (PS:^_^不错的php开发交流群:256271784,验证:csl,有兴趣的话可以加入进来一起讨论) function on_timer() { echo "timer called\n"; } /** * @param $func string, function name * @param $timeouts int, microtimes for time delay */ function timer($func, $timeouts){ echo "enter timer\n"; $base = event_base_new(); $event = event_new(); event_set($event, 0, EV_TIMEOUT, $func); event_base_set($event, $base); event_add($event, $timeouts); event_base_loop($base); } $pid = newChild("timer", "on_timer", 5000000); if ($pid > 0) { echo "master process exit\n"; }
PHP 擴展pcntl 實現” 多線程”( 進程)
pcntl 與ticks
ticks 是透過declare(ticks = n) {statement} 語法定義的, declare 語法目前只能接受ticks, 他定義的ticks = n 的意義是當declare 指定的語句區塊中執行了N 條低階語句去發生一個事件, 這個事件可以透過register_tick_function($function_name) 來註冊.
pcntl 的訊號機制是基於ticks 機制實現的. 因此, 我們使用pcntl 族函數中信號相關的函數時, 需要在前面增加declare(ticks = n) 語法結構.
int pcntl_alarm(int $seconds):
$seconds 秒後向進程發送一個SIGALRM 訊號, 每次呼叫pcntl_alarm 方法都會取消先前設定的時脈.
void pcntl_exec(string $path[, array $args[, array $env]]):
在目前行程空間執行程式.
$path: 必須是二進位執行檔, 或具有有效腳本頭資訊(#!/usr/local/bin/php) 的腳本檔路徑.
$args: 將要傳遞給該程式的字串參數列表( 數組形式)
$envs: 環境變數. 以數組(key => value 形式) 方式傳遞給要執行程式的環境變數.
int pcntl_for k (void):
建立一個子進程, 該子進程與父進程只是PID( 進程號) 和PPID( 父進程號) 不同.
在父線程執行時返回創建的子進程pid, 在子線程執行時返回0, 創建子進程失敗時會在父進程上下文返回-1, 並引發php 錯誤.
理解這裡的fork 需要知道: pcntl_fork 創建的是一個分支節點, 相當於一個標記, 父進程完成後, 子進程會從標記處繼續執行, 也就是說pcntl_fork 後面的程式碼分別被父進程和子進程執行了兩遍, 而兩個進程在執行過程中得到的返回值是不同的. 因此, 才可以分離父子進程執行不同的代碼.
int pcntl_getpriority([int $pid = getmypid()[, int $process_identifier = PRIO_PROCESS]]):
取得給定$pid 對應的程序的優先權, 預設是透過getmypid() 取得到的值也就是目前進程.
$pid: 如果沒有指定, 預設是當前進程.
$process_identifier: PRIO_PGRP, PRIO_USER, PRIO_PROCESS 三者之一, 預設PRIO_PROCESS. 其中PRIO_PGRP 指取得進程組的優先權, PRIO_USER 指標取得使用者行程的優先權, PRIO_PROCESS 指取得特定行程優先權.
傳回行程的優先權, 或在發生錯誤時傳回false, 值越小說明越優先
bool pcntl_setpriority(int $priority[, int $pid = getmypid()[, int $process_identifier = PRIO_PROCESS]]:
設定行程的優先權.
$priority: 優先權值, -20 到20 的範圍內, 預設優先權為0. 值為越小說明越優先.
$pid: 如果沒有指定, 指當前程序
$process_identifier: 意義同pcntl_getpriority 的$process_identifier.
設定成功回傳TRUE, 失敗回傳FALSE.
bool pcntl_signal_dispatch(signal_dispatch( void):
呼叫透過pcntl_signal() 安裝的即將發生的訊號的處理器.
呼叫成功返回TRUE,失敗回傳false.
php 5.3.3 加入
bool pcntl_signal(int $signo , callback $handler[, bool $restart_syscalls = true]):
為指定的訊號$signo 安裝一個新的訊號處理器$handler.
最後一個參數不明白意義.
bool pcntl_sigprocmask(int $how, array $set[, array &$oldset]):
增加, 刪除或設定鎖定訊號, 特定的行為依賴於$how 參數
$how: SIG_BLOCK 用於將訊號增加到目前鎖定訊號中, SIG_UNBLOCK 用於把訊號從目前鎖定訊號移除, SIG_SETMASK 用於用給定的訊號清單取代目前鎖定訊號.
$set: 要增加, 移除或設定的訊號清單.
$ oldset: 用於向呼叫者傳回舊的鎖定訊號.
成功傳回TRUE, 失敗回傳FALSE.
int pcntl_sigtimedwait(array $set[, array &$siginfo[, int $seconds = 0[, int $ nanoseconds = 0]]]):
pcntl_sigtimedwait 實際上和pcntl_sigwaitinfo() 所做的是同樣的事情, 不過pcntl_sigtimedwait 多了兩個增強的參數$seconds 和$nanoseconds, 這樣就允許腳本的停留時間有一個上限而不是無限制等待.
$set: 需要等待的信號列表
$siginfo: 用來向調用者返回等待得到的信號的信息, 信息內容見pcntl_sigwaitinfo
#$seconds: 超時的秒數
$nanoseconds: 超時的奈秒數
成功後, pcntl_sigtimedwiat() 傳回訊號編號
int pcntl_sigwaitinfo(array $set[, array &$siginfo]):
掛起目前腳本的執行, 直到接受到$set 中的某個訊號, 如果其中的一個訊號將要到達( 例如被pcntl_sigprocmask 鎖定) 那麼用來向呼叫者回傳等待得到的訊號的資訊, 此資訊包含以下內容:
1. 所有訊號所包含以下三個資訊:##a) signo: 訊號編號
b) signo: 訊號編號##b) signo: 訊號編號# : ##c) code: 訊號代碼
2. SIGCHLD 訊號特有的資訊
a) 記憶 stime: 系統消耗時間
d) pid: 發送進程id
e) uid: 傳送程序的真實使用者id
3. SIGILL #4. SIGPOLL 獨特的資訊:
a) band: band event, 意義未知
#b) fd:2102_$D
b) fd:2102_$poffffpfpffpfpfpfpfpfpfpfp
$status 用來保存子進程的狀態資訊, 此狀態資訊由下列函數產生: pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntlms, pcntlms,p .
$options: 如果你的系統允許wait3( 大多數的BSD 類別系統), 你可以提供一個可選的options 參數, 如果不提供這個參數, wait 將會使用系統呼叫, 如果系統不允許wait3 , 提供這個參數不會有任何影響, $options 的值可以是0 或WNOHANG 和WUNTRACED 兩個常數.
函數返回退出的子進程的PID, 或在錯誤時返回-1, 或者如果提供WNOHANG 作為option(wait3 不可用的系統) 並且無有效子程序返回0
殭屍進程: 由於父進程在fork 之後, 無法預知子進程什麼時候結束, 所以子進程為了要留給父進程一些信息, 會留下一個稱作殭屍的資料結構, 等待由父進程發起wait 的操作來為它收屍, 在子進程結束( 邏輯結束) 到父進程收屍前這段時間子進程就被稱為殭屍進程, 在父進程結束後, 所有的子程序會交由Init 來負責, 因此, 如果父進程結束, 殭屍進程都會被回收, 但是, 如果父進程永遠不結束, 這些殭屍進程就一直佔用進程號, 如果系統進程號耗盡, 那麼將導致無法啟動新進程, 因此, 安全的做法是在父進程中為自己產生的子進程去收屍.
int pcntl_waitpid(int $pid, int &$status[, int $options = 0 ]):
掛起當前進程直到給定$pid 的子進程退出, 或者當前進程接受到一個退出信號, 或者接受到一ige 信號去調用一個信號處理器.
如果給定$pid對應的子程序在呼叫此函數時已經退出( 殭屍態), 函數立刻返回, 所有的系統資源被釋放.
$pid: 進程號, 小於-1 表明等待的是進程組中的任何子進程, 進程組號就是$pid 的絕對值. 等於-1 表示等待任意紫禁城, 與pcntl_wait 函數行為一致. 等於0 代表等待與調用進程在同一組的子進程, 大於0 代表是特定的進程.
$status: 用來由函數傳回子進程狀態. 此狀態資訊由下列函數產生: pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig.##cxitoptions:ffpfpfid未來#ffpffp未來的意義> (int $status):
傳回一個已中斷的子程序回傳代碼, 此函數僅在pcntl_wifexited 函數傳回TRUE 時有用.
$status 參數是pcntl_waitpid 產生的狀態資訊.
bool pcntl_wifexited(int $status):
檢查給定狀態是否表明子進程是正常退出的.
bool pcntl_wifsignaled(int $status):
檢查給定狀態是否表明子進程是由於收到某個信號退出的.
bool pcntl_wifstopped(int $status):
檢查$status 是否能表明子進程當前已經停止, 這個函數只有在作用於pcntl_waitpid 函數使用的WUNTRACED 作為$options 參數的值時產生的$status上才有效.
int pcntl_wstopsig(int $status):
透過分析$status 返回使得子程序停止的信號的編號, 這個函數只有在pcntl_wifsignaled 返回TRUE 時才有效.
int pcntl_wtermsig(int $status):
返回讓進程中斷的訊號編號. 這個函數只有在pcntl_wifsignaled 返回TRUE 時才有效.
以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!
相關推薦:
PHP取整函數之ceil,floor,round,intval的區別解析
#########################################
以上是如何使用PHP中pcntl和libevent實現Timer功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

查看phpinfo()函數輸出、使用命令列工具和檢查PHP設定檔均可以查看php用了哪些擴充功能。 1.查看phpinfo()函數輸出,創建一個簡單的PHP腳本,將這個腳本保存為phpinfo.php,並將其上傳到您的網頁伺服器,在瀏覽器中存取此文件,使用瀏覽器的搜尋功能,在頁面中尋找關鍵字"extension"或"extension_loaded",以找到有關擴充功能的資訊即可。

如何使用PHP擴充PDO連接Oracle資料庫導語:PHP是一種非常流行的伺服器端程式語言,而Oracle是一款常用的關係型資料庫管理系統。本文將介紹如何使用PHP擴充PDO(PHPDataObjects)來連接Oracle資料庫。一、安裝PDO_OCI擴充要連接Oracle資料庫,首先需要安裝PDO_OCI擴充。以下是安裝PDO_OCI擴充的步驟:確保

如何使用PHP擴充SuiteCRM的報告產生功能SuiteCRM是一款功能強大的開源CRM系統,它提供了豐富的功能來幫助企業管理客戶關係。其中一個重要的功能是報告生成,使用報告可以幫助企業更了解業務狀況,並做出正確的決策。本文將介紹如何使用PHP擴充SuiteCRM的報告產生功能,並提供相關的程式碼範例。在開始之前,需要確保已經安裝好了SuiteCRM,

在使用PHP進行開發時,我們可能需要使用一些PHP擴充。這些擴充功能可以為我們提供更多的功能和工具,使我們的開發工作更有效率和便利。但在使用這些擴充功能之前,我們需要先進行安裝。本篇文章將為您介紹PHP擴充的安裝方法。一、什麼是PHP擴充? PHP擴充是指為PHP程式語言提供額外功能和服務的元件。這些組件可以透過PHP的擴充機制進行安裝和使用。 PHP擴充可以幫助我們處

PHP是一種流行的伺服器端腳本語言,它可以處理網頁上的動態內容。 PHP的geoip擴充功能可以讓你在PHP中取得有關使用者位置的資訊。在本文中,我們將介紹如何使用PHP的geoip擴充。什麼是PHP的GeoIP擴充? PHP的geoip擴展是一個免費的、開源的擴展,它允許你獲取有關IP位址和位置資訊的資料。此擴充功能可以與GeoIP資料庫一起使用,這是一個由MaxMin

宝塔面板是一款开源的服务器管理面板,在为网站运营者提供便捷的网站管理、数据库管理、SSL证书管理等服务的同时,还提供了强大的PHP扩展和PHP版本管理功能,让服务器管理变得更加简单和高效。一、PHP扩展PHP扩展是一种用来增强PHP功能的模块,通过安装PHP扩展可以实现更多的功能和服务,比如:加速器:加速器可以显著地提高PHP性能,通过缓存PHP脚本,减轻服

PHPPCNTL中fork失敗的常見錯誤及解決方案在使用PHPPCNTL擴充進行流程管理時,常會遇到fork失敗的問題。 fork是建立子程序的一種方法,在某些情況下可能會因為一些錯誤導致fork操作失敗。本文將介紹一些常見的fork失敗的錯誤以及相應的解決方案,並提供具體的程式碼範例來幫助讀者更好地理解和處理這些問題。 1.記憶體不足可能的錯誤訊息:Can

PHP擴充開發是創建自訂功能、擴展php核心功能並建立更強大的應用程式的藝術。它為PHP世界開闢了新的可能性,允許開發人員超越語言的基本限制。本文將帶您踏上PHP擴展開發的旅程,從基礎概念到進階技巧,為您提供全面的知識和實踐指南。 PHP擴充開發基礎在開始PHP擴充開發之前,您需要了解一些基礎概念。什麼是PHP擴充? PHP擴充是一種動態連結函式庫(DLL),它可以擴充PHP核心功能,提供新的資料型別、函式和類別。 PHP擴充的優點PHP擴充具有許多優點,包括:可擴充性、靈活性、效能最佳化和程式碼重複使用。 PHP
