首页 > 解决方案 > 如何更改此 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;
}

标签: c++multithreadingrandomcondition-variable

解决方案


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

#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 事件以优雅地结束所有线程


推荐阅读