我有一個充當服務器的類對象。它從任何地方接收請求,並在請求隊列中推送請求(Producer
)。現在有一個消費者線程正在運行,它將從請求隊列中彈出請求,並根據請求調用相應的類方法來提供請求。現在,正在以同步方式執行來自隊列的請求消耗和啓動適當的功能。我想要的是消費者線程彈出隊列中的請求並以異步方式啓動適當的功能,以便消費者可以立即彈出隊列中的下一個請求。C++中的異步函數
我嘗試過的一個解決方案是消費者從隊列中彈出一個請求並創建一個boost::thread
並在新線程中啓動相應的功能。我已經保存了std::vector
中的線程指針以及boost::thread_group
。到現在爲止還挺好。但是這個解決方案存在問題。
一旦我提供了超過150個請求,就有更多的150個線程,之後pthread
不會創建新的線程給出錯誤"pthread_create: Resource temporarily unavailable"
,我相信這意味着當前進程的堆棧已用完,因此無法創建新線程。
問題#1我的請求處理程序不包含while (1)
,而那些只是在做一些工作和退出,而不是等待任何東西,這就是爲什麼我期待我的初始線程已經完成了他們的處理和退出線程處理函數。考慮到這個問題,如果線程已經完成了處理並退出了,它不應該從堆棧中清理它的東西嗎?
這個問題的一個解決方案是我可以設置線程的堆棧大小,但是在說出1000個線程後仍然會引發此錯誤。
所以我的要求是我必須在一段時間後清理完成的線程(也就是說,當線程指針向量超過100或每隔1分鐘之後)。
問題#2除了像我上面提到的那樣啓動新線程,我應該嘗試使用其他異步函數調用機制。是boost::function
+ boost::bind
異步?這是我提到的情況的一個很好的解決方案嗎?假設我的系統應該每天24小時在線,並且每天都收到> 1000的請求。
更新#1 所以我在我的設計中發現一個問題。我在我的問題#1中提到我的請求處理程序只包含我發現的普通調用不是真的。它從服務器同步下載文件,這本質上是一個阻塞操作。我應該異步下載文件。
如果請求處理程序沒有執行任何阻止操作,則沒有任何方法可以使您的基礎系統無法併發處理線程。
所以,Alex提到有多個消費者線程(我認爲5個就足夠了)從隊列中彈出一個請求,並有一個異步文件下載將解決我的問題。
注意:創建比機器上的處理器更多的線程沒有多大意義。用N個線程創建一個線程池(其中N是您擁有的處理器數量)。讓線程池中的線程從隊列中彈出項目。由於套接字通信的阻塞性質,這是不夠的。您還需要查看異步IO,以便在進行時鐘調用時可以重用該線程。 –