簡體   English   中英

C ++ 11如何在1個線程中使用條件變量處理2個線程安全隊列

[英]C++11 How to handle 2 thread safe queues using condition variables in 1 thread

我有2個連接對象在各自的線程上運行,每個線程將不同的數據放入各自在主線程中運行的隊列。 因此,主線程有2個隊列,當其中一個隊列發出信號已將其放入數據時,需要將其喚醒。 我編寫了一個線程安全隊列,該隊列在theadsafe_queue內封裝了對條件變量的推送,彈出和信號傳遞。 但這似乎不起作用,因為在主循環中,它可能會阻塞第一個隊列,而數據可能進入第二個隊列,而不會被喚醒,反之亦然。
我是否必須在兩個隊列之間共享相同的條件變量和互斥量。 我可以修改我的threadsafe_queue以將條件變量和互斥鎖作為參數,並將相同的參數傳遞給每個隊列。 或者我在想,也許對每個隊列使用帶有計時器的wait_until,以便一旦出現超時就可以檢查每個隊列,但這似乎並不高效。 主處理線程具有大量帶有靜態對象/變量和容器的遺留代碼,因此在不引入大量鎖的情況下無法將其拆分為2個線程。 您認為什么是最好的方法。

合並隊列。

或者,編寫流系統。 生產者不需要知道他們的數據在哪里。 它必須走。 他們需要:

template<class T>
using sink=std::function<void(T)>;

發送他們的數據。

偵聽器不需要知道數據來自何處。 它需要一個來源:

template<class T>
using source= sink<sink<T>>;

現在它們處於不同的線程上; 因此,您需要一種從A到B獲取數據的方法。

template<class T>
struct threadsafe_queue {
  sink<T> get_sink();
  source<T> get_source();
};

在其中維護您的互斥鎖,條件變量和緩沖區。

現在,這是有趣的部分。 如果我們有X=variant<A,B> ,則接收sink<X>可以轉換為接收sink<A> (也可以將source<A>轉換為source<X> )。

因此,如果線程1產生A且線程2產生B ,它們甚至都可以不知道就饋入接收sink<X>

同時,使用者線程看到AB來自隊列。

您可以將source<T>=sink<sink<T>>替換為source<T>=std::function<std::optional<T>()> ,完成后返回空值。 我認為源頭是匯。 用途是:

void print_ints( source<int> src ) {
  src([](int x){ std::cout<<x<<','; });
  std::cout<<"\n";
}

與我不那么喜歡:

void print_ints( source<int> src ) {
  while(auto x=src()){std::cout<<*x<<','; };
  std::cout<<"\n";
}

順便說一句,您可以標記源/接收器類型和重載| 並添加pipe<In,Out>等。

但這在這里沒有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM