成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

PHP socket初探 --- 硬著頭皮繼續(xù)libevent(二)

jokester / 2733人閱讀

摘要:類就是產(chǎn)生各種不同類型事件的產(chǎn)出器,比如定時(shí)器事件讀寫事件等等,為了提升民族榮譽(yù)感,我們將這些各種事件比作各種戰(zhàn)斗機(jī)比如殲殲和殲。類就相對(duì)容易介入了,這玩意顯然就是一個(gè)航空母艦了,為了提升民族榮譽(yù)感,我們就把類當(dāng)作是遼寧艦。

[原文地址:https://blog.ti-node.com/blog...]

實(shí)際上php.net上是有event擴(kuò)展的使用說明手冊(cè),但是呢,對(duì)于初學(xué)者來說卻并沒有什么卵用,因?yàn)闆]有太多的強(qiáng)有力使用案例代碼,也沒有給力的User Contributed Notes,所以可能造成的結(jié)果就是:根本就看不懂。

這就是event文檔,點(diǎn)擊這里,你們可以感受一下。從文檔上看,event擴(kuò)展一共實(shí)現(xiàn)了如下圖幾個(gè)基礎(chǔ)類,其中最常用重要的就是Event和EventBase以及EventConfig三個(gè)類了,所以,先圍繞這三位開展一下工作。

考慮到你們、我、還有正在看這個(gè)文章的其他未知物種,大多數(shù)可能并不是搞C語(yǔ)言的老兵油子,所以我得用一些可能并不恰當(dāng)?shù)陌咐捅扔鱽韲L試引入這些概念。

libevent中有五個(gè)字母是event,實(shí)際上就是說“event才是王道”。

Event類就是產(chǎn)生各種不同類型事件的產(chǎn)出器,比如定時(shí)器事件、讀寫事件等等,為了提升民族榮譽(yù)感,我們將這些各種事件比作各種戰(zhàn)斗機(jī):比如殲10、殲15和殲20。

EventBase類就相對(duì)容易介入了,這玩意顯然就是一個(gè)航空母艦了,為了提升民族榮譽(yù)感,我們就把EventBase類當(dāng)作是遼寧艦。各種Event都必須依靠EventBase才能混口飯吃,這和戰(zhàn)斗機(jī)有遼寧艦才有底氣飛的更高更遠(yuǎn)是一個(gè)道理。一定是先有航母(EventBase),其次是戰(zhàn)斗機(jī)(Event)掛在航母(EventBase)上。

EventConfig則是一個(gè)配置類,實(shí)例化后的對(duì)象作為參數(shù)可以傳遞給EventBase類,這樣在初始化EventBase類的時(shí)候會(huì)根據(jù)這個(gè)配置初始化出不同的EventBase實(shí)例。類比的話,這個(gè)類則有點(diǎn)兒類似于遼寧艦的艦島,可以配置指揮整個(gè)遼寧艦。航空母艦的發(fā)展趨勢(shì)是不需要艦島的,同樣,在實(shí)例化EventBase類時(shí)候同樣也可以不傳入EventConfig對(duì)象,直接進(jìn)行實(shí)例化也是沒有問題的。

下面我們從開始寫一個(gè)php定時(shí)器來步入到代碼的節(jié)奏中。定時(shí)器是大家常用的一個(gè)工具,一般phper一說定時(shí)器,腦海中第一個(gè)想起的絕逼是Linux中的crontab。難道phper們離開了crontab真的就沒法混了嗎?是的,真的好羞恥,現(xiàn)實(shí)告訴我們就是這樣的,他們離開了crontab真的就沒法混了。那么,是時(shí)候通過純php來搞一波兒定時(shí)器實(shí)現(xiàn)了!

注意是真的純php,連Event擴(kuò)展都不用的那種。


代碼保存成timer.php,然后php timer.php運(yùn)行下,如果不出問題應(yīng)該能跑起來。但是吧,這個(gè)代碼有一坨問題。

首先是性能一般( 但是,比使用declare(ticks=1)還是要好不少的 )

其次是代碼量確實(shí)短小,短小的都讓人懷疑:這特么玩意能用?

最后是即便我硬著頭皮用,但這玩意只能精確到秒級(jí),逗我?

所以,為了解決以上問題,是時(shí)候操作一波兒Event擴(kuò)展了!

add( $tick );
// eventBase進(jìn)入loop狀態(tài)(遼寧艦!走你!)
$eventBase->loop();

將代碼保存為tick.php,然后php tick.php執(zhí)行一下,如下圖所示:

這種定時(shí)器是持久的定時(shí)器(每隔X時(shí)間一定會(huì)執(zhí)行一次),如果想要一次性的定時(shí)器(隔X時(shí)間后就會(huì)執(zhí)行一次,執(zhí)行過后再也不執(zhí)行了),那么將上述代碼中的“Event::TIMEOUT | Event::PERSIST”修改為“Event::TIMEOUT”即可。

如果你有一些自定義用戶數(shù)據(jù)傳遞給回調(diào)函數(shù),可以利用new Event()的第五個(gè)參數(shù),這五個(gè)參數(shù)可以給回調(diào)函數(shù)用,如下所示:

 "woshishui",
) );

需要重點(diǎn)說明的是new Event()這行代碼了,我把原型貼過來給大家看下:

public Event::__construct ( EventBase $base , mixed $fd , int $what , callable $cb [, mixed $arg = NULL ] )

第一個(gè)參數(shù)是一個(gè)eventBase對(duì)象即可

第二個(gè)參數(shù)是文件描述符,可以是一個(gè)監(jiān)聽socket、一個(gè)連接socket、一個(gè)fopen打開的文件或者stream流等。如果是時(shí)鐘時(shí)間,則傳入-1。如果是其他信號(hào)事件,用相應(yīng)的信號(hào)常量即可,比如SIGHUP、SIGTERM等等

第三個(gè)參數(shù)表示事件類型,依次是Event::READ、Event::WRITE、Event::SIGNAL、Event::TIMEOUT。其中,加上Event::PERSIST則表示是持久發(fā)生,而不是只發(fā)生一次就再也沒反應(yīng)了。比如Event::READ | Event::PERSIST就表示某個(gè)文件描述第一次可讀的時(shí)候發(fā)生一次,后面如果又可讀就緒了那么還會(huì)繼續(xù)發(fā)生一次。

第四個(gè)參數(shù)就熟悉的很了,就是事件回調(diào)了,意思就是當(dāng)某個(gè)事件發(fā)生后那么應(yīng)該具體做什么相應(yīng)

第五個(gè)參數(shù)是自定義數(shù)據(jù),這個(gè)數(shù)據(jù)會(huì)傳遞給第四個(gè)參數(shù)的回調(diào)函數(shù),回調(diào)函數(shù)中可以用這個(gè)數(shù)據(jù)。

通過以上的案例代碼可以總結(jié)一下日常流程:

創(chuàng)建EventConfig(非必需)

創(chuàng)建EventBase

創(chuàng)建Event

將Event掛起,也就是執(zhí)行了Event對(duì)象的add方法,不執(zhí)行add方法那么這個(gè)event對(duì)象就無法掛起,也就不會(huì)執(zhí)行

將EventBase執(zhí)行進(jìn)入循環(huán)中,也就是loop方法

捋清楚了定時(shí)器代碼,我們嘗試來解決一個(gè)信號(hào)的問題。比如我們的進(jìn)程是常駐內(nèi)存的daemon,再接收到某個(gè)信號(hào)后就會(huì)作出相應(yīng)的動(dòng)作,比如收到term信號(hào)后進(jìn)程就會(huì)退出、收到usr1信號(hào)就會(huì)執(zhí)行reload等等。

add();
// 進(jìn)入循環(huán)
echo "進(jìn)入循環(huán)".PHP_EOL;
$eventBase->loop();

將代碼保存成tick.php,然后執(zhí)行php tick.php,代碼已經(jīng)進(jìn)入循環(huán)了,然后我們打開另外一個(gè)終端,輸入ps aux|grep tick查看一個(gè)php進(jìn)程的pid進(jìn)程號(hào),對(duì)這個(gè)進(jìn)程發(fā)送term信號(hào),如下圖所示:


奇怪啊,從第一張圖看到確實(shí)收到term信號(hào)了,但是很奇怪為什么這個(gè)php進(jìn)程退出了呢?是因?yàn)闆]有添加Event::PERSIST,修改如下代碼如下:


有些心眼多雞賊的,IO多路復(fù)用的方法一共有三個(gè)select、poll和epoll(Mac下叫做kqueue),那么我們當(dāng)前的event擴(kuò)展用的是哪個(gè)方法呢?那么,再表演一波兒:

getMethod().PHP_EOL;
// 跑了許久龍?zhí)椎腸onfig這次也得真的露露手腳了
$eventConfig = new EventConfig;
// 避免使用方法kqueue
$eventConfig->avoidMethod("kqueue");
// 利用config初始化event base
$eventBase = new EventBase( $eventConfig );
echo "當(dāng)前event的方法是:".$eventBase->getMethod().PHP_EOL;

將代碼保存了,然后執(zhí)行一下,可以看到結(jié)果如下圖所示:

那么,還有一些更雞賊的人繼續(xù)發(fā)問,前面提到的邊緣觸發(fā)和水平觸發(fā),如何確認(rèn)呢?既然都用上epoll或者kqueue了,就一定要用邊緣觸發(fā)。

getFeatures();
// 看不到這個(gè)判斷條件的,請(qǐng)反思自己“位運(yùn)算”相關(guān)欠缺
if( $features & EventConfig::FEATURE_ET ){
  echo "邊緣觸發(fā)".PHP_EOL;
}
if( $features & EventConfig::FEATURE_O1 ){
  echo "O1添加刪除事件".PHP_EOL;
}
if( $features & EventConfig::FEATURE_FDS ){
  echo "任意文件描述符,不光socket".PHP_EOL;
}

運(yùn)行結(jié)果如下圖所示:

小小裝個(gè)逼總結(jié)一下,今兒這些個(gè)內(nèi)容就是講述event的基礎(chǔ)三大類,下個(gè)篇章依然是圍繞這三個(gè)家伙和IO操作結(jié)合到一起。

[原文地址:https://blog.ti-node.com/blog...]

[原文地址:https://blog.ti-node.com/blog...]

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/29394.html

相關(guān)文章

  • PHP socket初探 --- 含著淚也要磕完libevent(三)

    摘要:無數(shù)個(gè)專業(yè)送給啦啦啦啦,開始碼注意,將監(jiān)聽設(shè)置為非阻塞模式這里值得注意,我們聲明兩個(gè)數(shù)組用來保存事件和連接歡迎來到聊天室發(fā)言注意遵守當(dāng)?shù)胤煞ㄒ?guī)使用全局的和非阻塞模式下,注意的寫法會(huì)稍微特殊一些。 原文地址:https://t.ti-node.com/thread/... 這段時(shí)間相比大家也看到了,本人離職了,一是在家偷懶實(shí)在懶得動(dòng)手,二是好不容易想寫點(diǎn)兒時(shí)間全部砸到數(shù)據(jù)結(jié)構(gòu)和算法那里...

    suxier 評(píng)論0 收藏0
  • PHP socket初探 --- 顫顫抖抖開篇libevent(一)

    摘要:原文地址正如標(biāo)題所言,顫顫抖抖開篇。于是只能是你自己,把單子上的個(gè)快遞逐次和收到的對(duì)比一遍,然后對(duì)比完畢后再把這個(gè)單子給了阿梅,然后阿梅繼續(xù)等。剃光頭前的阿梅,就是,不敢正眼看老板娘一眼。剃光頭后的阿梅,就是,可徒手接魔鬼隊(duì)的死亡之球。 [原文地址:https://blog.ti-node.com/blog...] 正如標(biāo)題所言,顫顫抖抖開篇epoll。顫顫抖抖的原因大概也就是以前幾乎...

    levinit 評(píng)論0 收藏0
  • PHP socket初探 --- select系統(tǒng)調(diào)用

    摘要:原文地址在初探先從一個(gè)簡(jiǎn)單的服務(wù)器開始中依次講解了三個(gè)逐漸進(jìn)步的服務(wù)器只能服務(wù)于一個(gè)客戶端的服務(wù)器利用可以服務(wù)于多個(gè)客戶端的額服務(wù)器利用預(yù)派生進(jìn)程服務(wù)于多個(gè)客戶端的服務(wù)器最后一種服務(wù)器的進(jìn)程模型基本上的大概原理其實(shí)跟我們常用的是非常 [原文地址:https://blog.ti-node.com/blog...] 在<PHP socket初探 --- 先從一個(gè)簡(jiǎn)單的socket服務(wù)器開始...

    springDevBird 評(píng)論0 收藏0
  • PHP socket初探 --- 關(guān)于IO的一些枯燥理論

    摘要:原文地址要想更好了解編程,有一個(gè)不可繞過的環(huán)節(jié)就是在中,一切皆文件實(shí)際上要文件干啥不就是讀寫么所以,這句話本質(zhì)就是才是王道用的打開文件關(guān)閉文件讀讀寫寫,這叫本地文件在編程中,本質(zhì)就是網(wǎng)絡(luò)所以,在開始進(jìn)一步的編程前,我們必須先從概念上認(rèn)識(shí)好 [原文地址:https://blog.ti-node.com/blog...] 要想更好了解socket編程,有一個(gè)不可繞過的環(huán)節(jié)就是IO.在Lin...

    sf190404 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

jokester

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<