摘要:類就是產生各種不同類型事件的產出器,比如定時器事件讀寫事件等等,為了提升民族榮譽感,我們將這些各種事件比作各種戰斗機比如殲殲和殲。類就相對容易介入了,這玩意顯然就是一個航空母艦了,為了提升民族榮譽感,我們就把類當作是遼寧艦。
[原文地址:https://blog.ti-node.com/blog...]
實際上php.net上是有event擴展的使用說明手冊,但是呢,對于初學者來說卻并沒有什么卵用,因為沒有太多的強有力使用案例代碼,也沒有給力的User Contributed Notes,所以可能造成的結果就是:根本就看不懂。
這就是event文檔,點擊這里,你們可以感受一下。從文檔上看,event擴展一共實現了如下圖幾個基礎類,其中最常用重要的就是Event和EventBase以及EventConfig三個類了,所以,先圍繞這三位開展一下工作。
考慮到你們、我、還有正在看這個文章的其他未知物種,大多數可能并不是搞C語言的老兵油子,所以我得用一些可能并不恰當的案例和比喻來嘗試引入這些概念。
libevent中有五個字母是event,實際上就是說“event才是王道”。
Event類就是產生各種不同類型事件的產出器,比如定時器事件、讀寫事件等等,為了提升民族榮譽感,我們將這些各種事件比作各種戰斗機:比如殲10、殲15和殲20。
EventBase類就相對容易介入了,這玩意顯然就是一個航空母艦了,為了提升民族榮譽感,我們就把EventBase類當作是遼寧艦。各種Event都必須依靠EventBase才能混口飯吃,這和戰斗機有遼寧艦才有底氣飛的更高更遠是一個道理。一定是先有航母(EventBase),其次是戰斗機(Event)掛在航母(EventBase)上。
EventConfig則是一個配置類,實例化后的對象作為參數可以傳遞給EventBase類,這樣在初始化EventBase類的時候會根據這個配置初始化出不同的EventBase實例。類比的話,這個類則有點兒類似于遼寧艦的艦島,可以配置指揮整個遼寧艦。航空母艦的發展趨勢是不需要艦島的,同樣,在實例化EventBase類時候同樣也可以不傳入EventConfig對象,直接進行實例化也是沒有問題的。
下面我們從開始寫一個php定時器來步入到代碼的節奏中。定時器是大家常用的一個工具,一般phper一說定時器,腦海中第一個想起的絕逼是Linux中的crontab。難道phper們離開了crontab真的就沒法混了嗎?是的,真的好羞恥,現實告訴我們就是這樣的,他們離開了crontab真的就沒法混了。那么,是時候通過純php來搞一波兒定時器實現了!
注意是真的純php,連Event擴展都不用的那種。
代碼保存成timer.php,然后php timer.php運行下,如果不出問題應該能跑起來。但是吧,這個代碼有一坨問題。
首先是性能一般( 但是,比使用declare(ticks=1)還是要好不少的 )
其次是代碼量確實短小,短小的都讓人懷疑:這特么玩意能用?
最后是即便我硬著頭皮用,但這玩意只能精確到秒級,逗我?
所以,為了解決以上問題,是時候操作一波兒Event擴展了!
add( $tick ); // eventBase進入loop狀態(遼寧艦!走你!) $eventBase->loop();將代碼保存為tick.php,然后php tick.php執行一下,如下圖所示:
這種定時器是持久的定時器(每隔X時間一定會執行一次),如果想要一次性的定時器(隔X時間后就會執行一次,執行過后再也不執行了),那么將上述代碼中的“Event::TIMEOUT | Event::PERSIST”修改為“Event::TIMEOUT”即可。
如果你有一些自定義用戶數據傳遞給回調函數,可以利用new Event()的第五個參數,這五個參數可以給回調函數用,如下所示:
"woshishui", ) );需要重點說明的是new Event()這行代碼了,我把原型貼過來給大家看下:
public Event::__construct ( EventBase $base , mixed $fd , int $what , callable $cb [, mixed $arg = NULL ] )第一個參數是一個eventBase對象即可
第二個參數是文件描述符,可以是一個監聽socket、一個連接socket、一個fopen打開的文件或者stream流等。如果是時鐘時間,則傳入-1。如果是其他信號事件,用相應的信號常量即可,比如SIGHUP、SIGTERM等等
第三個參數表示事件類型,依次是Event::READ、Event::WRITE、Event::SIGNAL、Event::TIMEOUT。其中,加上Event::PERSIST則表示是持久發生,而不是只發生一次就再也沒反應了。比如Event::READ | Event::PERSIST就表示某個文件描述第一次可讀的時候發生一次,后面如果又可讀就緒了那么還會繼續發生一次。
第四個參數就熟悉的很了,就是事件回調了,意思就是當某個事件發生后那么應該具體做什么相應
第五個參數是自定義數據,這個數據會傳遞給第四個參數的回調函數,回調函數中可以用這個數據。
通過以上的案例代碼可以總結一下日常流程:
創建EventConfig(非必需)
創建EventBase
創建Event
將Event掛起,也就是執行了Event對象的add方法,不執行add方法那么這個event對象就無法掛起,也就不會執行
將EventBase執行進入循環中,也就是loop方法
捋清楚了定時器代碼,我們嘗試來解決一個信號的問題。比如我們的進程是常駐內存的daemon,再接收到某個信號后就會作出相應的動作,比如收到term信號后進程就會退出、收到usr1信號就會執行reload等等。
add(); // 進入循環 echo "進入循環".PHP_EOL; $eventBase->loop();將代碼保存成tick.php,然后執行php tick.php,代碼已經進入循環了,然后我們打開另外一個終端,輸入ps aux|grep tick查看一個php進程的pid進程號,對這個進程發送term信號,如下圖所示:
奇怪啊,從第一張圖看到確實收到term信號了,但是很奇怪為什么這個php進程退出了呢?是因為沒有添加Event::PERSIST,修改如下代碼如下:
有些心眼多雞賊的,IO多路復用的方法一共有三個select、poll和epoll(Mac下叫做kqueue),那么我們當前的event擴展用的是哪個方法呢?那么,再表演一波兒:
getMethod().PHP_EOL; // 跑了許久龍套的config這次也得真的露露手腳了 $eventConfig = new EventConfig; // 避免使用方法kqueue $eventConfig->avoidMethod("kqueue"); // 利用config初始化event base $eventBase = new EventBase( $eventConfig ); echo "當前event的方法是:".$eventBase->getMethod().PHP_EOL;將代碼保存了,然后執行一下,可以看到結果如下圖所示:
那么,還有一些更雞賊的人繼續發問,前面提到的邊緣觸發和水平觸發,如何確認呢?既然都用上epoll或者kqueue了,就一定要用邊緣觸發。
getFeatures(); // 看不到這個判斷條件的,請反思自己“位運算”相關欠缺 if( $features & EventConfig::FEATURE_ET ){ echo "邊緣觸發".PHP_EOL; } if( $features & EventConfig::FEATURE_O1 ){ echo "O1添加刪除事件".PHP_EOL; } if( $features & EventConfig::FEATURE_FDS ){ echo "任意文件描述符,不光socket".PHP_EOL; }運行結果如下圖所示:
小小裝個逼總結一下,今兒這些個內容就是講述event的基礎三大類,下個篇章依然是圍繞這三個家伙和IO操作結合到一起。[原文地址:https://blog.ti-node.com/blog...]
[原文地址:https://blog.ti-node.com/blog...]
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/29394.html
摘要:無數個專業送給啦啦啦啦,開始碼注意,將監聽設置為非阻塞模式這里值得注意,我們聲明兩個數組用來保存事件和連接歡迎來到聊天室發言注意遵守當地法律法規使用全局的和非阻塞模式下,注意的寫法會稍微特殊一些。 原文地址:https://t.ti-node.com/thread/... 這段時間相比大家也看到了,本人離職了,一是在家偷懶實在懶得動手,二是好不容易想寫點兒時間全部砸到數據結構和算法那里...
摘要:原文地址正如標題所言,顫顫抖抖開篇。于是只能是你自己,把單子上的個快遞逐次和收到的對比一遍,然后對比完畢后再把這個單子給了阿梅,然后阿梅繼續等。剃光頭前的阿梅,就是,不敢正眼看老板娘一眼。剃光頭后的阿梅,就是,可徒手接魔鬼隊的死亡之球。 [原文地址:https://blog.ti-node.com/blog...] 正如標題所言,顫顫抖抖開篇epoll。顫顫抖抖的原因大概也就是以前幾乎...
摘要:原文地址在初探先從一個簡單的服務器開始中依次講解了三個逐漸進步的服務器只能服務于一個客戶端的服務器利用可以服務于多個客戶端的額服務器利用預派生進程服務于多個客戶端的服務器最后一種服務器的進程模型基本上的大概原理其實跟我們常用的是非常 [原文地址:https://blog.ti-node.com/blog...] 在<PHP socket初探 --- 先從一個簡單的socket服務器開始...
摘要:原文地址要想更好了解編程,有一個不可繞過的環節就是在中,一切皆文件實際上要文件干啥不就是讀寫么所以,這句話本質就是才是王道用的打開文件關閉文件讀讀寫寫,這叫本地文件在編程中,本質就是網絡所以,在開始進一步的編程前,我們必須先從概念上認識好 [原文地址:https://blog.ti-node.com/blog...] 要想更好了解socket編程,有一個不可繞過的環節就是IO.在Lin...
閱讀 2977·2023-04-25 17:22
閱讀 1542·2019-08-30 15:54
閱讀 1270·2019-08-30 15:53
閱讀 1787·2019-08-30 15:43
閱讀 3020·2019-08-29 12:29
閱讀 1232·2019-08-26 11:37
閱讀 3255·2019-08-23 18:02
閱讀 1604·2019-08-23 14:15