libevent多線程

使用libevent編寫多線程服務端

一、設計框架:

1)主線程監聽連接各種事件,創建多個工作線程處理具體業務

2)收到連接時創建對象管理,並綁定到一個線程

3)主線程監聽到一個讀事件,將該連接添加到所綁定的線程的處理隊列

4)工作線程一次取出隊列元素,從bufferevent讀取數據,並處理

 

二、、設置bufferevent爲多線程安全(也就是每次讀寫bufferevent都是上鎖的)

1)設置多線程支持

#ifdef WIN32

evthread_use_windows_threads();

#else

evthread_use_pthreads();

#endif

 

2)創建bufferevent時加上BEV_OPT_THREADSAFE標誌

struct bufferevent *bev = NULL;

bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE);

 

3)此後使用bufferevent緩存就是線程安全的

當然在自己的代碼中也可以使用bufferevent的鎖

bufferevent_lock(bev);

/*............中間這部分已經加鎖...........*/

bufferevent_unlock(bev);  

 

 

三、使用智能指針(std::shared_ptr<type> nodeptr(new type))管理連接對象

1)原因:

創建了一個對象來管理一個連接(bufferevent),在多線程中,可能主線程監聽到斷開連接,這時就會刪除該對象,但是,此時可能工作線程中正通過對象對連接的數據進行處理,如果刪除了該對象,造成的後果很可能時段錯誤-程序崩潰。

2)因此:

收到連接時創建一個智能指針指向連接對象,並用容器保存。

收到連接讀事件時,將該連接對象的智能指針傳到工作線程的處理隊列。

線程取出智能指針後,通過該智能指針調用對象接口。

此時,及時主線程從容器中刪除了該智能指針,但是線程中正通過同一對象的智能指針調用對象,對象實際上就不會刪除,只有等待工作線程處理結束並跳出智能指針的棧範圍,連接對象纔會實際刪除。

 

如果工作線程處理完對象後,需要向連接寫數據,那麼一定要注意加鎖、加判斷條件,因爲此時可能連接已經斷開了。

 

 

發佈了48 篇原創文章 · 獲贊 12 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章