2012-08-22 357 views
2

當我們想要設計一個通用的事件處理(I/O解複用)或反應堆模式模型。我們使用的底層系統調用是「select」或「poll」。但是這兩個系統調用在通用FD上都不是線程安全的。不能用於多線程環境。C++中的多線程事件處理

通過多個I/O的多線程處理事件會是更好的方法。

我可以看到的1種方式是,主線程recv的任何事件並推入到線程池的共享隊列中。但工作線程無法通過I/O發送數據導致同步問題。內存溢出也有缺點。

歡迎您提出所有可能的建議。提前致謝。

+0

我會ASIO調查升壓一些信息和epoll的替代抽象/ kqueue的,它包裝了你的底層細節,並且你可以使用一個更好的界面,它可以處理各種io「事件」,並允許你將自己的事件「發佈」到「隊列」中進行處理...... – Nim

+0

You' d使用一個線程進行輪詢,並將實際的I/O分配給工作線程(超出線程池)。 –

回答

0

一種方法是擁有一個輸入線程,一個輸出線程,多個工作線程和兩個阻塞隊列。

輸入線程解析輸入消息並將它們放入隊列1.工作線程全部等待隊列1,處理消息並放置它們在隊列2中的任何輸出。輸出線程在隊列2上等待並序列化輸出。

InputThread: 
    Loop: 
     M = ReadNextMessage 
     Q1.push(M) 

AddOutput(O): 
    Q2.push(O) 

WorkerThread: 
    Loop: 
     M = Q1.pop 
     ProcessMessage(M) using AddOutput as needed 

OutputThread: 
    Loop: 
     O = Q2.pop 
     WriteOutput(O) 

但是,我不知道你的意思是選擇不是線程安全嗎?所有的系統調用在技術上是線程安全的

這是很老,但還是很有意思的是所謂的「CY10K問題」被稱爲凱格爾傢伙的文章..

http://www.kegel.com/c10k.html

它討論了不同的方式來構建一個「多io「程序在Linux上的優缺點。

+0

'select'與相同的fd不是線程安全的。你應該讀過manuel。 –

+0

@ J-16SDiZ你能解釋一下嗎?你的意思是如果fd_set在線程之外,然後多線程調用select使用fd_set? –

+0

@ J-16SDiZ:錯誤。選擇是線程安全的,如POSIX手冊中所述:http://stackoverflow.com/questions/12084704/select-on-same-fd-from-multiple-sockets –

0

檢查出"Producer - Consumer problem",這是線程安全問題的一個非常好的起點。它也可以擴展到多個生產者和多個消費者。

1

大多數Unix系統提供更多的可擴展性的替代選擇/民意調查,可以在多線程環境中使用:

但在多線程環境中正確使用它可能會非常棘手,因此您可能需要查看現有的抽象N層像boost.asio

在另一方面,Boost.Asio的確實引入了一些不可忽視的開銷 - 我收集關於在http://nginetd.cmeerw.org

+0

謝謝..我會經歷這些反思。 – Naveen