處理大併發之三 對libevent的初步認識

2021-07-22 18:12:43 字數 4346 閱讀 8588

首先翻譯下

裡的一段文章

對非同步io

的乙個簡要介紹

大多數應用程式都是阻塞的io

呼叫,如果

io呼叫是同步(阻塞)的,它不能立即返回直到它的操作完成,或者經過了很長時間直到網路棧丟棄。當你在乙個

tcp連線上呼叫」connect()」時,例如,你的作業系統從tcp

連線的另一端主機排隊等待乙個

syn包時。它不能立即返回你的應用程式,直到從連線的另一端主機收到

syn ack

包,或者經歷了足夠的時候,驅動層丟棄。

libevent簡要介紹

libevent是乙個輕量級的開源高效能網路庫。

libevent特點:(來自 )

(1)事件驅動(

event-driven

),高效能;

(2)輕量級,專注於網路,不如 

ace 

那麼臃腫龐大;

(3)源**相當精煉、易讀

(4)跨平台,支援 

windows

、linux

、*bsd

和 mac os

;(5)支援多種 

i/o多路復用技術,

epoll

、poll

、dev/poll

、select 

和kqueue 

等;(6)支援 

i/o,定時器和訊號等事件;

(7)註冊事件優先順序;

libevent 已經被廣泛的應用,作為底層的網路庫;比如 

memcached

、 vomi t

、 nylon

、 netchat

等等。

至目前為止資料也看了一部分,原始碼也看了一部分,我覺得研究原始碼,查資料,分析原始碼都很重要,但是最關鍵的是做demo

分析demo。

現在想使用libevent

做乙個服務端的程式,結合之前使用

epoll

做的客戶端程式做測試。

剛開始的時候在網上找了乙個demo

,結果編譯不過,折騰半天還是放棄了。

鬱悶了半天,找到乙個例子不錯,分享出來,我自己分析了下,修改了一些細節然後加了些注釋,****於:

(尊重原創)

對了,這裡不在陳述libevent

的安裝,之前在研究

memcache

其實安裝基本都是./configure –prefix=路徑,然後

make && make install

就可以了

服務端demo

**:libevent_server.c

[cpp]view plain

copy

#include 

#include 

#include 

#include 

#include 

#define listen_port 8000

#define listen_backlog 32

void do_accept_cb(evutil_socket_t listener, short event, void *arg);  

void read_cb(struct bufferevent *bev, void *arg);  

void error_cb(struct bufferevent *bev, short event, void *arg);  

void write_cb(struct bufferevent *bev, void *arg);  

int main(int argc, char *argv)  

evutil_make_listen_socket_reuseable(listener);//埠重用,檢視原始碼evutil.c中可以知道就是對setsockopt做了層封裝,之所以這樣做是因為為了和win32 networking api相容

struct sockaddr_in sin;  

sin.sin_family = af_inet;  

sin.sin_addr.s_addr=htonl(inaddr_any);  

sin.sin_addr.s_addr=inet_addr("127.0.0.1");  

sin.sin_port = htons(listen_port);  

if (bind(listener, (struct sockaddr *)&sin, sizeof(sin)) 

if (listen(listener, listen_backlog) 

printf ("listening...\n");  

evutil_make_socket_nonblocking(listener);//設定為非阻塞模式,檢視原始碼evutil.c中可以知道就是對fcntl做了層封裝

struct event_base *base = event_base_new();//建立乙個event_base物件也既是建立了乙個新的libevent例項

if (!base)   

//建立並繫結乙個event

struct event *listen_event;  

listen_event = event_new(base, listener, ev_read|ev_persist, do_accept_cb, (void*)base);  

event_add(listen_event, null);//註冊時間,引數null表示無超時設定

event_base_dispatch(base);//)程式進入無限迴圈,等待就緒事件並執行事件處理

printf("the end.");  

return 0;  

}  void do_accept_cb(evutil_socket_t listener, short event, void *arg)  

printf("accept: fd = %u\n", fd);  

//使用bufferevent_socket_new建立乙個struct bufferevent *bev,關聯該sockfd,託管給event_base

struct bufferevent *bev = bufferevent_socket_new(base, fd, bev_opt_close_on_free);//bev_opt_close_on_free表示釋放buff

erevent時關閉底層傳輸埠。這將關閉底層套接字,釋放底層bufferevent等。  

bufferevent_setcb(bev, read_cb, null, error_cb, arg);  

bufferevent_enable(bev, ev_read|ev_write|ev_persist);//啟用read/write事件

}  void read_cb(struct bufferevent *bev, void *arg)  

}  void write_cb(struct bufferevent *bev, void *arg) {}  

void error_cb(struct bufferevent *bev, short event, void *arg)  

else

if (event & bev_event_eof)   

else

if (event & bev_event_error)   

bufferevent_free(bev);  

}  

編譯:gcc -i/usr/include -o 123 libevent_server.c -l/usr/local/lib -levent

注意這裡應該是包含檔案的路徑和庫檔案的路徑加上去,具體路徑取決於安裝目錄

測試1:

:將客戶端的併發數設定為

2,檢視執行結果

服務端:

客戶端:

測試2:將客戶端的併發數設定為

10000

,(如果沒有修改核心,需要修改控制代碼的最大數,

ulimit 

–n 65535)檢視埠占用結果:

lsof 

–i:8000 >log

grep 

「tcp localhost.localdomain」

log |wc 

–l 檢視埠占用

20001

,結果正確,測試成功。

from: 

(三)對極幾何

對極約束理解 1.對於有重疊紋理的兩幀影象,通過特徵點匹配可以找到一些匹配對,這是對極幾何約束的基礎 2.匹配對是由同一空間點在不同畫素平面投影得到的不同畫素座標,以參考幀為基礎,假設空間點為 p 參考幀投影畫素為 p 當前幀投影畫素為 p 由於空間點 p 深度值不確定,因此其可能在參考幀光心 o ...

三對老虎過河問題

abc三隻母老虎,孩子分別為abc三隻小老虎,已知abca都會划船,bc不會。每次過河船上最多坐兩隻老虎,可兩大或兩小或一大一小一起過。但一大一小老虎在一起時,如果不是母子關係,那麼小老虎會被吃掉,請設計乙個合理的過河方案。ab過,abcc ab a回,aabcc b ac過,abc abc a回,...

Linux curses 總結三(對鍵盤的操作)

cbreak cooked 預處理模式 curses程式的控制模式函式 curses程式的鍵盤操作函式 小栗子curses程式的鍵盤操作是對底層的簡單封裝介面 cooked 標準輸入模式,處理的是一行資料,每次遇到 r 換行符 才會把輸入到快取的資料傳遞給程式,這種情況下鍵盤輸入特殊字元可以被處理 ...