epoll用法說明,ET模式下的邊緣觸發處理同時多事件
#include <map>
#include <vector>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#include <sys/time.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#include <
#include <string>
#include <cstdio>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <cstdlib>
#include <cctype>
#include <sstream>
#include <utility>
#include <stdexcept
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <signal.h>
usingnamespace std;
#pragma pack(1)
//管道訊息結構
struct pipemsg {
int op;
int fd;
unsigned int ip;
};
//地址埠結構
struct ipport {
unsigned int ip;
unsigned short port;
booloperator< (const ipport rhs) const{return (ip < rhs.ip || (ip == rhs.ip && port < rhs.port));}
booloperator== (const ipport rhs) const{return (ip == rhs.ip && port == rhs.port);}
};
//對應於對方地址埠的連線資訊
struct peerinfo {
int fd; //對應連線控制代碼
unsigned int contime; //最後連線時間
unsigned int rcvtime; //收到資料時間
unsigned int rcvbyte; //收到位元組個數
unsigned int sndtime; //傳送資料時間
unsigned int sndbyte; //傳送位元組個數
};
//連線結構
struct conninfo {
int rfd; //管道讀端
int wfd; //管道寫端
map<struct ipport, struct peerinfo> peer; //對方資訊
};
#pragma pack()
//全域性執行標誌
bool g_bRun;
//全域性連線資訊
struct conninfo g_ConnInfo;
void setnonblocking(int sock)
{
int opts;
opts = fcntl(sock,F_GETFL);
if (opts <0)
{
perror("fcntl(sock,GETFL)");
exit(1);
}
opts = opts|O_NONBLOCK;
if (fcntl(sock, F_SETFL, opts) <0)
{
perror("fcntl(sock,SETFL,opts)");
exit(1);
}
}
void setreuseaddr(int sock)
{
int opt;
opt =1;
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(&opt)) <0)
{
perror("setsockopt");
exit(1);
}
}
staticvoid sig_pro(int signum)
{
cout <<"sig_pro, recv signal:"<< signum << endl;
if (signum == SIGQUIT)
{
g_bRun =false;
}
}
//接收連線執行緒
void* AcceptThread(void*arg)
{
cout <<"AcceptThread, enter"<< endl;
int ret; //臨時變數,存放返回值
int epfd; //監聽用的epoll
int listenfd; //監聽socket
int connfd; //接收到的連線socket臨時變數
int i; //臨時變數,輪詢陣列用
int nfds; //臨時變數,有多少個socket有事件
struct epoll_event ev; //事件臨時變數
constint MAXEVENTS =1024; //最大事件數
struct epoll_event events[MAXEVENTS]; //監聽事件陣列
socklen_t clilen; //宣告epoll_event結構體的變數,ev用於註冊事件,陣列用於回傳要處理的事件
struct sockaddr_in cliaddr;
struct sockaddr_in svraddr;
unsigned short uListenPort =5000;
int iBacklogSize =5;
int iBackStoreSize =1024;
struct pipemsg msg; //訊息佇列資料
//建立epoll,對2.6.8以後的版本,其引數無效,只要大於0的數值就行,核心自己動態分配
epfd = epoll_create(iBackStoreSize);
if (epfd <0)
{
cout <<"AcceptThread, epoll_create fail:"<< epfd <<",errno:"<< errno << endl;
return NULL;
}
//建立監聽socket
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd <0)
{
cout <<"AcceptThread, socket fail:"<< epfd <<",errno:"<< errno << endl;
close(epfd);
return NULL;
}
//把監聽socket設定為非阻塞方式
setnonblocking(listenfd);
//設定監聽socket為埠重用
setreuseaddr(listenfd);
//設定與要處理的事件相關的檔案描述符
ev.data.fd = listenfd;
//設定要處理的事件型別
ev.events = EPOLLIN|EPOLLET;
//註冊epoll事件
ret = epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);
if (ret !=0)
{
cout <<"AcceptThread, epoll_ctl fail:"<< ret <<",errno:"<< errno << endl;
close(listenfd);
close(epfd);
return NULL;
}
bzero(&svraddr, sizeof(svraddr));
svraddr.sin_family = AF_INET;
svraddr.sin_addr.s_addr = htonl(INADDR_ANY);
svraddr.sin_port=htons(uListenPort);
bind(listenfd,(sockaddr *)&svraddr, sizeof(svraddr));
//監聽,準備接收連線
ret = listen(listenfd, iBacklogSize);
if (ret !=0)
{
cout <<"AcceptThread, listen fail:"<< ret <<",errno:"<< errno << endl;
close(listenfd);
close(epfd);
return NULL;
}
while (g_bRun)
{
//等待epoll事件的發生,如果當前有訊號的控制代碼數大於輸出事件陣列的最大大小,超過部分會在下次epoll_wait時輸出,事件不會丟
nfds = epoll_wait(epfd, events, MAXEVENTS, 500);
//處理所發生的所有事件
for (i =0; i < nfds && g_bRun; ++i)
{
if (events[i].data.fd == listenfd) //是本監聽socket上的事件
{
cout <<"AcceptThread, events:"<< events[i].events <<",errno:"<< errno << endl;
if (events[i].events&EPOLLIN) //有連線到來
{
do
相關推薦
epoll用法說明,ET模式下的邊緣觸發處理同時多事件
#include <deque> #include <map> #include <vector> #include <pthread.h> #include <semaphore.h> #in
epoll學習筆記(ET模式下事件觸發原理和資料收發存在的問題)
這篇文章所講的例子和情況可以結合《epoll的LT模式和ET模式 》這篇看。 epoll有兩種模式,Edge Triggered(簡稱ET) 和 Level Triggered(簡稱LT).在採用這兩種模式時要注意的是,如果採用ET模式,那麼僅當狀態發生變化時才會通知,而採
Epoll在LT和ET模式下的讀寫方式和區別
LT模式:epoll就是一個快速版poll,可讀可寫就緒條件和傳統poll一致 ET模式:為了避免Starvation,建議 1)檔案描述符設定為非阻塞 2)只在read或write返回EAGAIN後,才能呼叫下一次epoll
epoll在LT和ET模式下的讀寫方式
在一個非阻塞的socket上呼叫read/write函式, 返回EAGAIN或者EWOULDBLOCK(注: EAGAIN就是EWOULDBLOCK) 從字面上看, 意思是: * EAGAIN: 再試一次 * EWOULDBLOCK: 如果這是一個阻塞socket
epoll反應堆及ET模式下的EPOLLOUT學習總結
學習epoll反應堆發現網上的epoll反應堆都是同一份程式碼框架… 自己理解、梳理一遍,思路在註釋裡 #include <stdlib.h> #include <stdio.h> #include <stdio.h>
Epoll-ET模式下非阻塞讀寫之Buffer的封裝
先說說Epoll的ET模式 epoll預設的模式是LT,要說ET不得不提到LT,LT與ET的區別可以用一句話概括: LT模式下只要socket處於可讀狀態(新增EPOLLIN事件時)或可寫
EPOLL在ET模式下會被觸發多次麼?
前幾天和同學一起討論EPOLLONESHOT的作用,它的功能是這樣的: 對於註冊了EPOLLONESHOT事件的檔案描述符,作業系統最多觸發其上註冊的包括可讀,可寫,錯誤中的一個,且只觸發一次 剛一看感覺EPOLLONESHOT咋麼就是ET模式相對於LT模
RedisTemplate執行lua指令碼,叢集模式下報錯解決
redis叢集配置: 在使用spring的RedisTemplate執行lua指令碼時,報錯EvalSha is not supported in cluster environment,不支援cluster。 程式碼: @Test public
Vue開發及上線過程中遇到的坑(axios跨域,history模式下空白頁問題)
最近公司在用vue開發一個網站,在這過程中,遇到了一些需要注意的點,在此先列出來,防止下次再次踩坑 1.在開發環境下,使用axios進行資料互動時,如果遇到跨域問題的話,可以在如下圖 Config檔案下的index.js 設定proxy代理 你可以新建一個專門放介面
Linux系統忘記root密碼,緊急模式下更改密碼
測試 http passwd inf 界面 str 下界 eboot -s linux忘記密碼命令概括: 1.開機按e,rd.break,ctrl+x; 2.mount -o remount,rw /sysroot 3.chroot /sysroot
MVVM模式下 所有控制元件共享同一事件 以TextBox只能輸入數字鍵和回車鍵為例子
一:首先對MvvmLight裡的ViewModel進行封裝 封裝完畢後讓ViewModel繼承DialogViewModel public class DialogViewModel : ViewModelBase { public voi
div和內部的a標籤都有click事件,點選a不觸發div的click事件
<div> <a></a> </div> $("a").click(function(){ event.stopPropagation(); }) 詳情見: https://blog.csdn.net/u0
VM虛擬機網絡在Bridge模式下,本機不能連接SSH問題的解決
機器 checksum 模式 load iptable off pos disable ssh設置 今天遇到了一個很奇怪的問題。 VM虛擬機網絡連接原先在NAT模式下,本機通過SSH訪問沒有任何問題,但切換到Bridge模式後,SSH死活都連接不上。以為是自己SSH設
改進Vim體驗:在插入模式下移動光標,我不要用方向鍵!alt快捷鍵使用技巧!
targe 判斷 映射 tar 什麽 nbsp .vimrc 一次 time 改進Vim體驗:在插入模式下移動光標,我不要用方向鍵!alt快捷鍵使用技巧! 大家都知道,我們在插入模式下編輯代碼的時候 若想寫完這一部分後,移動到鄰近的一部分,如下一個單詞的後面,是很復雜的
SQL Server SQL性能優化之--數據庫在“簡單”參數化模式下,自動參數化SQL帶來的問題
參考 itl stat 數據行 img tro while 第一次 line 數據庫參數化的模式 數據庫的參數化有兩種方式,簡單(simple)和強制(forced),默認的參數化默認是“簡單”,簡單模式下,如果每次發過來的SQL,除非完全一樣
高性能網絡服務器編程:為什麽linux下epoll是最好,Netty要比NIO.2好?
系統 工作效率 lee socket 為我 handler 10g 函數 適合 基本的IO編程過程(包括網絡IO和文件IO)是,打開文件描述符(windows是handler,java是stream或channel),多路捕獲(Multiplexe,即select和poll
epoll的水平觸發和邊緣觸發,以及邊緣觸發為什麽要使用非阻塞IO
alt 開啟 本機 另一個 trigger stdio.h 什麽 我們 水平 轉自:http://www.cnblogs.com/yuuyuu/p/5103744.html 一.基本概念
flask的debug模式下,網頁輸入pin碼進行調試
lsp png 資源文件 post 上下文 .com highlight lai target 網站後端Python+Flask .FLASK調試模式之開啟DEBUG與PIN使用? 自動加載: # 方式一 1 2 if __nam
grub legacy練習 之破壞MBR中的Bootloader,而後在救援模式下修復之
修復centos啟動1. 用dd命令對grub進行破壞2.然後重啟,鏡像位置選擇正確後,會出現下圖界面,點擊Rescue救援模式進行救援;3.跳過網卡設置,直接選擇Continue選項進行救援;4.點擊OK5.點擊OK5.然後出現下邊的命令行,輸入命令之後,如圖(quit錯誤,是exit)6.出現如圖所示開
安裝glibc錯誤鏈接導致系統崩潰,u盤啟動緊急救援模式下修復系統。
-bash 回車 符號 根目錄 image ali 崩潰 mbo config Sln 命令 創建動態符號鏈接 用法 sln source dest 故障案例:一個誤操作 導致了一個不小的故障,輸入所有命令都無效,直接系統無法啟動。 故障描述 sln /