gpt4 book ai didi

C++11 线程 : Multiple threads waiting on a condition variable

转载 作者:可可西里 更新时间:2023-11-01 17:31:45 24 4
gpt4 key购买 nike

我目前正在研究一个模拟扩展生产者- worker 模型的问题。在这个问题中,有 3 个 worker 和 3 个工具可用,要让 worker 工作,他们需要 2 个工具(和 Material ,但这些无关紧要)。如果金库中有 >=2 个工具, worker 将拿取 2 个。否则,他们将等待一个条件变量,该变量将在 >=2 个时发出信号。

这对 2 个 worker 来说没问题:一个工作然后将工具归还到金库,另一个等待的 worker 将被唤醒并拿走 2 个工具。问题是,有 3 个 worker ,总会有一个人饿着肚子去拿工具。

经过一些测试后,我注意到等待条件变量的线程是以堆栈形式构建的。有没有可能让它排队?(1等,2等,3等。当1觉醒想再做一个的时候,就得在2和3后面等。)

这是一个示例输出。代码太长,所以如果真的有必要,我会发布它。有 3 个工作线程和 1 个工具互斥体。挨饿的人每隔一段时间就会有所不同。

1 Tools taken. Remaining: 1
2 Waiting on tools...
3 Waiting on tools...
1 Operator Product made. Tools returned. Tools now:3
3 Tools taken. Remaining: 1
1 Waiting on tools...
3 Materials returned for switch.
3 Operator Product made. Tools returned. Tools now:3
1 Tools taken. Remaining: 1
3 Waiting on tools...
1 Materials returned for switch.
1 Operator Product made. Tools returned. Tools now:3
3 Tools taken. Remaining: 1
1 Waiting on tools...
3 Materials returned for switch.
3 Operator Product made. Tools returned. Tools now:3
1 Tools taken. Remaining: 1
3 Waiting on tools...
1 Materials returned for switch.
1 Operator Product made. Tools returned. Tools now:3
3 Tools taken. Remaining: 1
1 Waiting on tools...
3 Materials returned for switch.
3 Operator Product made. Tools returned. Tools now:3
1 Tools taken. Remaining: 1
3 Waiting on tools...
1 Materials returned for switch.
...

(如您所见,2 永远不会得到工具...)

更新:2013/07/05我添加了一些代码。

int tools = 3; //global
string last; //current last product on output buffer
mutex toolsMutex;
mutex matSearchMutex;

int main() {
//Initializing Producers
Producer prod1(1);
Producer prod2(2);
Producer prod3(3);

thread p1(processor,1);
thread p2(processor,2);
thread p3(processor,3);

p1.detach();
p2.detach();
p3.detach();

while(true) {//forever running
}

return 0;
}

处理器:

//Processor method
void processor(int i) {
srand(time(NULL));

while (true) { //forever running

bool hasTools = false;
bool productMade = false;
while (productMade == false) { //while product has yet to be made.
//choose what to make...
if (hasTools == false) {
thread matT(getMaterials,whatToMake);
thread toolT(getTools,i);
toolT.join();
matT.join();
hasTools = true;
}
else { //tools acquired but no materials
thread matT(getMaterials,whatToMake);
matT.join();
}

if (recordedLast.compare(last) != 0) {

//return materials and acquire new ones the next run

continue;
}
else {
makeProduct(whatToMake);
unique_lock<mutex> locker(toolMutex);
tools = tools + 2;
cout << i << " Operator Product made. Tools returned. Tools now:" << tools << endl;
productMade = true;
if (tools >=2)
toolsCV.notify_one();
}

//done processing

}
}
}

制造产品:

void makeProduct(int i) {
unique_lock<mutex> mainMatLock(matSearchMutex);
// make product according to i
this_thread::sleep_for(chrono::milliseconds(rand() % 1000 + 10));
}

获取工具:

void getTools(int i) {
unique_lock<mutex> locker(toolMutex);
if (tools <2) {
cout << i << " Waiting on tools..." << endl;
toolsCV.wait(locker);
}
tools = tools - 2;//tools acquired
cout << i <<" Tools taken. Remaining: " << tools << endl;
}

感谢回复的人。今晚我将尝试使用多个条件变量实现一个等待队列。

(附:在 Stack Overflow 上是否有更好的代码格式化方法?除了四个空格之外......

最佳答案

std::condition_variable 未指定调用 notify_one 时唤醒哪个等待线程。因此,您应该编写不关心哪个线程被唤醒的代码。标准模式是无论哪个线程被唤醒,该线程都应该完成需要完成的工作。

如果您需要以特定顺序唤醒线程,则使用不同的机制。例如,您可以为每个线程设置一个单独的 std::condition_variable,然后在需要工具时将线程放入队列中。当一个线程提交工具时,它可以向队列前面的线程对应的条件变量发出信号。然后该线程将被唤醒,而其他线程将继续休眠(模假唤醒)。

关于C++11 线程 : Multiple threads waiting on a condition variable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17419893/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com