C++11如何在1个线程中使用条件变量处理2个线程安全队列
C++11 How to handle 2 thread safe queues using condition variables in 1 thread
我有两个连接对象在各自的线程上运行,每个线程都将不同的数据放入在主线程中运行的相应队列中。因此,主线程有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>
等。
但这在这里没有用。
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 类与私有变量的其他类之间的线程安全性
- 全局变量 多读取器 一个写入器多线程安全?
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 成员变量在多线程 C++ 时自行更改
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- 多个线程可以安全地同时将相同的值写入同一变量吗?
- C++11:具有互斥锁的线程看到原子变量的值发生变化,尽管这是唯一可以改变它的代码
- C++线程不检测全局变量更改
- 为什么 beginthreadex 线程参数变量在父线程中没有更新
- C++多线程程序:变量定义为类成员的隔离错误
- std::线程不是全局变量,但在到达创建它的函数的末尾时不会超出范围?
- 对全局变量的多线程访问:我应该使用互斥锁吗?
- 子线程中的条件变量等待停止主线程中的执行
- cuda:多个线程访问同一个全局变量
- 多个线程可以读取同一个类成员变量吗?
- 线程局部变量的初始化顺序
- 在静态初始化期间,pthread线程变量何时开始存在
- 从主循环windows访问线程变量
- 线程变量的声明和影响