2011-06-16 74 views
2

我正在使用C++的網絡程序,我想實現一個pthread池。每當我收到來自接收套接字的事件時,我都會將數據放入線程池中的隊列中。我正在考慮創建5個獨立的線程,並會持續檢查隊列以查看是否有任何傳入數據要完成。pthread池,C++

這是非常直接的話題,但我不是專家,所以我想聽到任何可能有助於實現這一點。

請讓我知道任何教程或引用或我應該注意的問題。

+0

經過一番搜索:http://stackoverflow.com/q/5799924/14065 – 2011-06-16 03:54:37

+0

一個天真的線程池是很容易實現,但其對短期頻繁的任務的性能可能會很差。 – 2011-06-16 04:49:27

+0

@Gene:你需要定義short。對人來說短暫是處理器的永恆。 – 2011-06-16 04:58:49

回答

4

使用Boost.Asio並且每個thread在池中調用io_service::run()

多個線程可以調用 io_service對象:: run()中設立的 線程從完成處理 可調用的游泳池。這種方法也可以與io_service :: post()一起使用,以便使用 一種方法在線程池中執行任何計算 任務。

注意,已加入 用一個io_service的池中的所有線程都認爲 等同,並且在 武斷的方式。該io_service可以 分佈在它們之間的工作。

0

讓接收線程推送隊列中的數據,5個線程彈出它。使用互斥體保護隊列,讓他們爲數據「拼搏」。

你也想在工作線程的主循環

+0

能給我更多的細節爲什麼我需要usleep(和pthread_yield()?在此先感謝.. – codereviewanskquestions 2011-06-16 02:38:21

+1

使用usleep的繁忙循環不是一個好的解決方案 – 2011-06-16 03:04:45

0

你需要一個互斥體和條件變量usleep()函式或pthread_yield()。互斥體將保護您的作業隊列,並且當接收到線程時將作業添加到隊列中,它將發信號通知條件變量。工作線程將等待條件變量,並在發送信號時喚醒。

0

Boost asio是一個很好的解決方案。

但是,如果你不想使用它(或不能使用它出於任何原因),那麼你可能會想使用基於信號量的實現。

您可以找到根據,我在這裏使用的信號量多線程隊列實現:

https://gist.github.com/482342

之所以使用信號量是可以避免在工作線程不斷地輪詢,而是讓他們醒來當需要完成的工作時由操作系統啓動。

1

在我開始之前。
使用boost ::線程

如果你想知道如何用pthread的做到這一點,那麼你需要使用pthread條件變量。這些允許您掛起正在等待工作而不消耗CPU的線程。

當一個工作項目被添加到隊列中時,表示條件變量和一個pthread將從條件變量中釋放,從而允許它從隊列中取出一個項目。當線程完成處理工作項時,它將返回到條件變量以等待下一項工作。

循環中線程的主循環應該如下所示;

ThreadWorkLoop()     // The function that all the pool threads run. 
{ 
    while(poolRunnin) 
    { 
     WorkItem = getWorkItem(); // Get an item from the queue. This suspends until an item 
     WorkItem->run();   // is available then you can run it. 
    } 
} 
GetWorkItem() 
{ 
    Locker lock(mutex);    // RAII: Lock/unlock mutex 
    while(workQueue.size() == 0) 
    { 
     conditionVariable.wait(mutex); // Waiting on a condition variable suspends a thread 
    }         // until the condition variable is signalled. 
             // Note: the mutex is unlocked while the thread is suspended 
    return workQueue.popItem(); 
} 
AddItemToQueue(item) 
{ 
    Locker lock(mutex); 
    workQueue.pushItem(item); 
    conditionVariable.signal();  // Release a thread from the condition variable. 
} 
+0

有關使用boost :: theads的好主意(至少直到C + +11),但暫停線程和使用鎖定不應該輕易採取,它會在短而頻繁的任務中破壞性能,通常會使用某種自旋計數器來減少浪費。 – 2011-06-16 03:22:54