[英]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>
。
同時,使用者線程看到A
或B
來自隊列。
您可以將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.