c++ - 如何更改此notify_one以便选择随机线程?

标签 c++ multithreading random condition-variable

在此先感谢您的帮助。
尝试制作一个可以创建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;
}

最佳答案

您可以为每个线程使用一个条件变量,开始时每个线程都应使用false,然后将随机条件变量更改为true并通知所有,这将使一个随机线程唤醒(拥有该条件变量的线程) )
这是完整的解决方案

#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();
    }
}
请注意,这里我使用头UserInterruptHandler.h处理CTR + C事件以正常结束所有线程

关于c++ - 如何更改此notify_one以便选择随机线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58611573/

相关文章:

android - 如何等到线程完成

php - Mysql 两张表,从一张表中选取所有值,比较是否存在,然后返回一个随机值

c++ - 将 OpenCV 窗口嵌入到 Qt GUI 中

c++ - 指向任意类方法的模板非类型指针

c++ - 根据模板参数有条件地启用成员函数

钻石设计中最后派生的 C++ 基类函数调用

c++ - 在线程应用程序中从 QtScript 调用的 Qt 槽

java - 通过java程序启动tomcat startup.bat

c++ - 在哪里初始化随机种子以通过多个随机模块使用?

python - 如何让一个数字在一定百分比的时间内随机出现 - 重复出现?