use*_*367 5 c++ multithreading semaphore thread-safety
使用线程打印奇偶数 我遇到了这个问题,想讨论 C++ 中的解决方案。我可以想到使用 2 个二进制信号量奇数和偶数信号量。偶数信号量初始化为 1,奇数信号量初始化为 0。
**T1 thread function**
funOdd()
{
wait(even)
print odd;
signal(odd)
}
**T2 thread function**
funEven()
{
wait(odd)
print even
signal(even)
}
Run Code Online (Sandbox Code Playgroud)
除此之外,如果我的函数只生成数字并且有第三个线程 T3 将打印这些数字,那么理想的设计应该是什么?我使用了一个数组,其中奇数将放置在奇数位置,偶数将放置在偶数位置。T3 将从这个数组中读取,这将避免对该数组的任何线程安全,如果 T3 没有找到任何索引,那么它将等待该索引被填充。另一种解决方案是使用一个队列,该队列将有一个互斥锁,T1 和 T2 在插入时可以使用该互斥锁。
请对此解决方案发表评论,以及如何使其更有效率。
编辑以使问题更清楚:总体问题是我有两个生产者(T1,T2)和一个消费者(T3),并且我的生产者是相互依赖的。
使用条件变量
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mu;
std::condition_variable cond;
int count = 1;
void PrintOdd()
{
for(; count < 100;)
{
std::unique_lock<std::mutex> locker(mu);
cond.wait(locker,[](){ return (count%2 == 1); });
std::cout << "From Odd: " << count << std::endl;
count++;
locker.unlock();
cond.notify_all();
}
}
void PrintEven()
{
for(; count < 100;)
{
std::unique_lock<std::mutex> locker(mu);
cond.wait(locker,[](){ return (count%2 == 0); });
std::cout << "From Even: " << count << std::endl;
count++;
locker.unlock();
cond.notify_all();
}
}
int main()
{
std::thread t1(PrintOdd);
std::thread t2(PrintEven);
t1.join();
t2.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么您要使用三个单独的线程来实现串行行为。但无论如何我都会回答:)
一种解决方案是使用修改后的生产者/消费者模式,并在生产者和消费者之间设置优先队列。队列上的排序操作将取决于发布消息的整数值。消费者将查看队列中的一个元素并检查它是否是下一个期望的元素。如果没有,它将睡眠/等待。
一些代码:
class Elt implements Comparable<Elt> {
int value;
Elt(value) { this.value=value; }
int compare(Elt elt);
}
class EltQueue extends PriorityBlockingQueue<Elt> { // you shouldn't inherit colelctions, has-a is better, but to make it short
static EltQueue getInstance(); // singleton pattern
}
class Consumer{
Elt prevElt = new Elt(-1);
void work()
{
Elt elt = EltQueue.getInstance().peek();
if (elt.getValue() == prevElt.getValue()+1)) {
EltQueue.getInstance().poll();
//do work on Elt
}
}
}
class Producer {
int n=0; // or 1!
void work() {
EltQueue.getInstance().put(new Elt(n+=2));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21478 次 |
| 最近记录: |