c++ - 如何更改此 notify_one 以使其选择随机线程?
问题描述
提前感谢您的帮助。尝试制作一个创建 6 个线程的程序,然后每 2 秒随机选择一个并使其打印其编号。我显然做错了什么,因为它只是不停地打印 0-1-2-3-4-5 。代码如下。主要问题是,我应该怎么做才能使随机线程解锁?
#include <thread>
#include <memory>
#include <chrono>
#include <condition_variable>
std::condition_variable* cv = new std::condition_variable();
std::mutex cv_m;
void threadFunc(std::shared_ptr<bool> flag2, int id)
{
while (true)
{
std::unique_lock<std::mutex> lock(cv_m);
cv->wait(lock);
if (true)
if (*flag2) std::cout << "Thread" << " " << id << std::endl;
}
}
int main() {
std::shared_ptr<bool> f2 = std::make_shared<bool>(false);
std::thread threads[6];
for (int i = 0; i < 6; i++)
threads[i] = std::thread(threadFunc, f2, i);
*f2 = true;
while (true)
{
cv->notify_one();
std::this_thread::sleep_for(std::chrono::seconds(2));
}
return 0;
}
解决方案
您可以为每个线程使用一个条件变量,一开始每个线程应该为假,然后将随机条件变量更改为真并通知所有,这将使一个随机线程唤醒(拥有该条件变量的线程) 这里是完整的解决方案
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <unistd.h>
#include "UserInterruptHandler.h"
using namespace std;
UserInterruptHandler h;
condition_variable conditionalVariable;
mutex mtx;
bool flag = true;
void myMethod(int id, bool *canWork) {
unique_lock<mutex> ul(mtx);
while (flag) {
conditionalVariable.wait(ul,[=]{return *canWork;});
if(!flag)
break;
cout << "thread " << id << endl;
}
cout << "thread " << id << " exits.." << endl;
}
int main() {
cout << "input thread count" << endl;
int n;
cin >> n;
thread myThreads[n];
bool *canWork = new bool[n];
for (int i = 0; i < n; i++) {
canWork[i] = false;
myThreads[i] = thread(myMethod, i + 1, &canWork[i]);
}
while (!h.checkInterruption()) {
int i = rand() % n;
canWork[i] = true;
conditionalVariable.notify_all();
canWork[i] = false;
usleep(1000);
}
flag = false;
int i = 0;
for (thread &th:myThreads) {
canWork[i++] = true;
conditionalVariable.notify_all();
if (th.joinable())
th.join();
}
}
请注意,这里我使用 headerUserInterruptHandler.h
来处理 CTR+C 事件以优雅地结束所有线程
推荐阅读
- bash - 如何远程杀死进程ID Bash
- r - 如何在R中为边缘着色并向桑基图添加标签
- python - 在 Keras 自定义损失函数中有效使用 SciPy 函数?
- azure-devops - YAML 使用变量在参数上设置值
- google-sheets - Google 表格 - 基于标准的列表中的最佳组合
- flutter - RangeError(索引):无效值:有效值范围为空:0错误Flutter
- git - 如何将我在一个 Git 存储库中所做的所有更改合并到另一个存储库?
- python-3.x - 它什么都不做,但我认为算法是真的你能告诉我错误在哪里吗?
- javascript - 移动设备上的 Vuetify Select 不会在单击滚动时关闭
- c# - 在 c# 中中止新对象的构造,而是返回对已经存在的对象的引用的最干净的方法是什么?