繁体   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