徹底學會使用epoll(四)——ET的寫操作例項分析
首先,看程式四的例子。
l 程式四
點選(此處)摺疊或開啟
-
#include <unistd.h>
-
#include <iostream>
-
#include <sys/epoll.h>
-
using namespace std;
-
int main(void)
-
{
-
int epfd,nfds;
-
struct epoll_event ev,events[5];//ev用於註冊事件,陣列用於返回要處理的事件
-
epfd=epoll_create(1);//只需要監聽一個描述符——標準輸出
-
ev.data.fd=STDOUT_FILENO;
-
ev.events=EPOLLOUT|EPOLLET;//監聽讀狀態同時設定ET模式
-
epoll_ctl(epfd,EPOLL_CTL_ADD,STDOUT_FILENO,&ev);//註冊epoll事件
-
for(;;)
-
{
-
nfds=epoll_wait(epfd,events,5,-1);
-
for(int i=0;i<nfds;i++)
-
{
-
if(events[i].data.fd==STDOUT_FILENO)
-
cout<<"hello world!"<<
-
}
-
}
- };
這個程式的功能是隻要標準輸出寫就緒,就輸出“hello world!”。
執行結果:
我們發現這將是一個死迴圈。下面具體分析一下這個程式的執行過程:
(1) 首先初始buffer為空,buffer中有空間可寫,這時無論是ET還是LT都會將對應的epitem加入rdlist(對應第一節圖中的紅線),導致epoll_wait就返回寫就緒。
(2) 程式想標準輸出輸出”hello world!”和換行符,因為標準輸出為控制檯的時候緩衝是“行緩衝”,所以換行符導致buffer中的內容清空,這就對應第二節中ET模式下寫就緒的第二種情況——當有舊資料被髮送走時,即buffer
我們再看程式五。
l 程式五
相對程式四這裡僅僅去掉了輸出的換行操作。即:
cout<<"hello world!";
執行結果如下:
我們看到程式成掛起狀態。因為第一次epoll_wait返回寫就緒後,程式向標準輸出的buffer中寫入“hello world!”,但是因為沒有輸出換行,所以buffer中的內容一直存在,下次epoll_wait的時候,雖然有寫空間但是ET模式下不再返回寫就緒。回憶第一節關於ET的實現,這種情況原因就是第一次buffer為空,導致epitem加入rdlist,返回一次就緒後移除此epitem,之後雖然buffer仍然可寫,但是由於對應epitem已經不再rdlist中,就不會對其就緒fd的events的在檢測了。
l 程式六
點選(此處)摺疊或開啟
-
int main(void)
-
{
-
int epfd,nfds;
-
struct epoll_event ev,events[5];//ev用於註冊事件,陣列用於返回要處理的事件
-
epfd=epoll_create(1);//只需要監聽一個描述符——標準輸出
-
ev.data.fd=STDOUT_FILENO;
-
ev.events=EPOLLOUT;//使用預設LT模式
-
epoll_ctl(epfd,EPOLL_CTL_ADD,STDOUT_FILENO,&ev);//註冊epoll事件
-
for(;;)
-
{
-
nfds=epoll_wait(epfd,events,5,-1);
-
for(int i=0;i<nfds;i++)
-
{
-
if(events[i].data.fd==STDOUT_FILENO)
-
cout<<"hello world!";
-
}
-
}
- };
程式六相對程式五僅僅是修改ET模式為預設的LT模式,我們發現程式再次死迴圈。這時候原因已經很清楚了,因為當向buffer寫入”hello world!”後,雖然buffer沒有輸出清空,但是LT模式下只有buffer有寫空間就返回寫就緒,所以會一直輸出”hello world!”,當buffer滿的時候,buffer會自動刷清輸出,同樣會造成epoll_wait返回寫就緒。
l 程式七
點選(此處)摺疊或開啟
-
int main(void)
-
{
-
int epfd,nfds;
-
struct epoll_event ev,events[5];//ev用於註冊事件,陣列用於返回要處理的事件
-
epfd=epoll_create(1);//只需要監聽一個描述符——標準輸出
-
ev.data.fd=STDOUT_FILENO;
-
ev.events=EPOLLOUT|EPOLLET;//監聽讀狀態同時設定ET模式
-
epoll_ctl(epfd,EPOLL_CTL_ADD,STDOUT_FILENO,&ev);//註冊epoll事件
-
for(;;)
-
{
-
nfds=epoll_wait(epfd,events,5,-1);
-
for(int i=0;i<nfds;i++)
-
{
-
if(events[i].data.fd==STDOUT_FILENO)
-
cout<<"hello world!";
-
ev.data.fd=STDOUT_FILENO;
-
ev.events=EPOLLOUT|EPOLLET;
-
epoll_ctl(epfd,EPOLL_CTL_MOD,STDOUT_FILENO,&ev); //重新MOD事件(ADD無效)
-
}
-
}
- };
程式七相對於程式五在每次向標準輸出的buffer輸出”hello world!”後,重新MOD OUT事件。所以相當於每次重新進行第一節中紅線描述的途徑返回就緒,導致程式迴圈輸出。
相關推薦
徹底學會使用epoll(四)——ET的寫操作例項分析
首先,看程式四的例子。 l 程式四 點選(此處)摺疊或開啟 #include <unistd.h> #include <iostream> #include <sys/epoll.h> using namespace s
徹底學會使用epoll(三)——ET的讀操作例項分析
首先看程式一,這個程式想要實現的功能是當用戶從控制檯有任何輸入操作時,輸出”hello world!”。 l 程式一 點選(此處)摺疊或開啟 #include <unistd.h> #include <iostream> #incl
NOIP複賽複習(四)讀寫外掛與高精度模板
讀入輸出掛 讀入輸出掛就是逐個字元地讀入資料,從而讓讀入更加快速。輸出掛的原理也是一樣的,都是通過將輸出數字變成輸出字元以加快速度。當然輸入輸出外掛一般用在大量輸入輸出的情況下,這樣價效比才高一些,否則得不償失。 void Rd(int &res){ &nbs
TensorFlow神經網路(四)手寫數字識別
內容來自mooc人工智慧實踐第五講 一、MNIST資料集一些用到的基礎函式語法 ############ warm up ! ############ # 匯入imput_data模組 from tensorflow.examples.tutorials.mnist import
Html5 學習系列(四)文件操作API
activex 出了 1.0 for AD con dsta buffer 們的 原文:Html5 學習系列(四)文件操作API 引言 在之前我們操作本地文件都是使用flash、silverlight或者第三方的activeX插件等技術,由於使用了這些技術後
spring 官方文件的介面理解整理(四)型別轉換spring例項解析
上篇文章解析了spring型別轉換的介面和他們的分工,怎麼通過設計模式實現轉換功能。 這篇需要些上篇的知識,如果沒有看可以從這兒跳轉spring 官方文件的介面理解整理(三)型別轉換 一、準備新建Maven專案,pom.xml內容如下 <properties>
OpenCV學習筆記(30)KAZE 演算法原理與原始碼分析(四)KAZE特徵的效能分析與比較
KAZE系列筆記: 1. OpenCV學習筆記(27)KAZE 演算法原理與原始碼分析(一)非線性擴散濾波 2. OpenCV學習筆記(28)KAZE 演算法原理與原始碼分析(二)非線性尺度空間構
Solr學習筆記(四)----使用solrJ操作
solrJ是solr官方類庫,實現原理就是使用http請求和響應,只是進行了一層封裝,不需要寫請求的url等引數。 使用solrJ操作solr索引庫的一些方法: 1、向solr索引庫新增文件 @Test public void testAddDocument() throws Exc
SpringBoot2.0原始碼分析(四):spring-data-jpa分析
SpringBoot具體整合rabbitMQ可參考:SpringBoot2.0應用(四):SpringBoot2.0之spring-data-jpa JpaRepositories自動注入 當專案中存在org.springframework.data.jpa.repository.JpaRepositor
深入併發之(四) 執行緒池詳細分析
執行緒池的分類 首先我們需要了解,使用執行緒池的目的。如果我們有大量的較短的非同步任務需要執行,那麼我們需要頻繁的去建立執行緒並關閉執行緒。那麼這樣做的代價是十分巨大的,因此,我們就採用了一種執行緒池的做法,實際上,我們常用了池類方式還有資料庫連線池,這種一般是將一些比較珍貴的資源放在池中,然後,每次使用完畢
Activiti的學習(四)——流程變數操作、任務型別
ProcessEngine pe = null; @Before public void init() { pe = ProcessEngines.getDefaultProcessEngine(); } 一、流程變數操作 流程變數指的是
【SpringMVC】10.REST風格的CRUD實戰(四)之刪除操作
注意!!! 一、前情提要 刪除操作 URL:emp/{id} 請求方式:DELETE 刪除後效果:對應記錄從資料表中刪除 二、具體步驟 1.配置HiddenHttpMethodFilter 由於HTML只支援常見的Get和POST方法,而DELE
(四)DFS檔案操作的原理及程式碼實現
1、檔案操作原理 1.1、下載過程 Client向namenode發起Open file 請求。目的是獲取指定檔案的輸入流 namenode收到請求之後,會檢查路徑的合法性,客戶端的操作許可權。如果檢測未通過,則直接報錯返回 Client也會向namenode發起Get
python語法(四)— 文件操作
並不會 head == ber odi tel 三個參數 lines python 前面幾天學習了一寫python的基礎語法,也學習了分支if,循環while和for。由於之前已經做過幾年的開發了,所以我們知道,許多數據來源並不是靠鍵盤輸入到程序中去的,而是通過數據庫和文件
python 基礎篇(四)字典常用操作方法
# 字典類似Map一樣的{key,value}結構; # 字典建立 userMap ={"name":"王力巨集","age":"18","love":"dog"} ; print(userMap) # 字典取值,根據key進行取值 get(key) name = userMap.get("na
EventBus原始碼分析(四):執行緒模型分析(2.4版本)
EventBus有四種執行緒模型 PostThread模式不需執行緒切換,直接在釋出者執行緒進行事件處理。 MainThread模式分類討論:釋出者執行緒是主執行緒則直接呼叫事件處理方法,否則通過Handler進行執行緒切換,切換到主執行緒處理事件,該模
Java NIO框架Netty教程(四) – ServerBootStrap啟動流程原始碼分析
該圖是OneCoder通過閱讀Netty原始碼,逐漸記錄下來的。基本可以說明Netty服務的啟動流程。這裡在具體講解一下。 首先說明,我們這次順利的流程是基於NioSocketServer的。也就是基於Java NIO Selector的實現方式。在第六講《Java NIO框架Netty教程(六)-Jav
Spring第一課:基於XML裝配bean(四),三種例項化方式:預設構造、靜態工廠、例項工廠
Spring中基於XML中的裝配bean有三種方式: 1.預設構造 2.靜態工廠 3.例項工廠 1.預設構造 在我們在Spring的xml檔案中直接通過: <bean id="名字" class="全限定類名" ></bea
H5移動端開發基礎(四)多指操作、案例-相簿
多指操作、案例-相簿 多指操作 旋轉 縮放 實現安卓多指事件 案例-相簿 多指操作 // gesturestart:手指觸碰元素,螢幕上有兩個或兩個以上的手指 oBox.addEventListener
jvm(四)——JVM自帶記憶體分析工具詳解
在進行java程式問題定位時,記憶體問題定位是很關鍵的一招。jvm自帶的命令可以方便的在生產監控和列印堆疊的日誌資訊幫忙我們來定位問題!雖然jvm調優成熟的工具已經有很多:jconsole、大名鼎鼎的VisualVM,IBM的Memory Analyzer等等,