2013-01-14 47 views
3

以某種方式跟進this question。我只想知道在boost::asio:io_service所處理的函數中是否可以使用std::mutex?股的使用是不切實際的。從我在boost reference中發現的東西中,我會說沒關係。由於它聲明對boost :: asio管理的線程池使用std :: mutex

異步完成處理程序只能從當前正在調用io_service :: run()的線程中調用。

所以其他由boost創建的線程不應該干涉。我是否正確?

回答

8

是的,在處理程序中使用std::mutex是非常好的。一個strand只是一個僞裝畢竟僞裝的隊列。

+0

那麼,什麼是使用asio股然後呢? – PSIAlt

2

boost僅從其角度調用回調。此回調與boost沒有任何關係,因此boost不在意您在回調中所做的操作。所以採取鎖定(使用任何你想要的鎖定庫),都是非常好的。

9

正如其他人已經指出,std::mutex和其他鎖定機制,可以在處理程序內使用。然而,兩者之間存在根本的區別:

  • 處理程序中的外部鎖定機制用於保護資源免受競爭條件影響。
  • A strand用於消除處理程序之間的爭用,從而導致處理程序之間的爭用條件被移除。

如果整個處理程序被同步爲潛在的競爭條件與其他的處理程序,而不是螺紋外部的線程池的結果,那麼我想強調的同步的外部機構之間的細微差異之一和boost::asio::strand

考慮以下情形:

  • 的2個線程線程池與Boost.Asio的實現。
  • 處理程序AB將在同一互斥體上進行同步。
  • 處理程序C不需要同步。
  • 處理程序ABC被張貼到io_service中。

AB被調用。線程池現在由於外部同步而耗盡,因爲兩個線程都正在使用。不幸的是,其中一個線程在資源上被阻塞,導致不需要同步的處理程序(如C)位於隊列中。

如果在這種情況下使用一個鏈進行同步,那麼這個飢餓實例就不會發生。 A strand維護其自己的處理程序隊列,並且保證其處理程序中只有一個處理程序在io_service中,導致處理程序在被放入io_service之前被同步。在這種情況下,如果AB已過帳到strand,那麼strand將過帳Aio_service。這將導致ACio_service中,允許C同時運行,而B保持在strand的隊列中,等待A完成。

此外,還有一些使用情況,可以同時使用這兩種形式的同步。例如,考慮資源與在線程池之外運行的線程共享的情況。線程池內部和外部的線程仍需要互斥。但是,可以使用strand來消除線程池內部線程之間的互斥爭用。

+0

確實如此。在我的情況下,我想使用鏈和互斥的混合,因爲我有一些大的函數,在某些時候需要共享資源。但我認爲阻止整個函數運行的資源是一個矯枉過正的行爲。我想,將這些函數分解成許多小的函數,會將asio線程池的開銷顯着增加。 – Haatschii

0

完成處理程序中的互斥鎖可以阻止線程執行。在這種情況下,您需要比boost::thread::hardware_concurrency()更多的io_service線程來加載100%的CPU。它增加了線程切換開銷。