Y (O - O) Y 2023-05-12 22:17 采纳率: 50%
浏览 26

c++ 多线程 条件变量问题

c++ 多线程: 请问为什么我在主线程里使用条件变量唤醒子线程没有反应,子线程不打印信息

#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <Windows.h>

using namespace std;

mutex mymutex;
condition_variable mCond;
bool f = false;

class Thread { // 自定义线程类
public:
    typedef void (*CallBackFunc) (void*);
    bool start(void* arg);
    bool detach();
    bool join();
    thread::id id;
    Thread() :mArg(nullptr), mIsStart(false), mIsDetach(false) {};
    Thread(CallBackFunc c) :mArg(nullptr), mIsStart(false), mIsDetach(false), c(c) {};
    ~Thread();
    void handle(void* arg) { c(arg); };
private:
    void run(void* arg);
    void* threadRun(void*);
    void* mArg;
    bool mIsStart;
    bool mIsDetach;
    thread mThreadId;
    CallBackFunc c;
};

bool Thread::start(void* arg)
{
    mArg = arg;
    mThreadId = thread(&Thread::threadRun, this, this);
    mIsStart = true;
    id = this_thread::get_id();
    return true;
}

bool Thread::detach()
{
    if (!mIsStart) { return false; }
    if (mIsDetach) { return true; }
    mThreadId.detach();
    mIsDetach = true;
    return true;
}

bool Thread::join()
{
    if (!mIsStart || mIsDetach) { return false; }
    mThreadId.join();
    return true;
}

Thread::~Thread()
{
    if (mIsStart && !mIsDetach) { detach(); }
}

void* Thread::threadRun(void* arg)
{
    Thread* t = (Thread*)arg;
    t->run(t->mArg);
    return nullptr;
}

void Thread::run(void* arg) {
    handle(arg);

}

void action1(void* arg) {
    while (!f)
    {
        unique_lock<mutex> sb(mymutex);
        mCond.wait(sb, [&]() {
            return f;
        });
        int* x = (int*)arg;
        cout << "thread id: " << this_thread::get_id() << " x: " << x << endl;
    }
}


int main() {
    
    int x = 1;
    vector<Thread*> v;
    for (int i = 0; i < 5; i++) {
        v.push_back(new Thread(action1));
        v[i]->start((void*)x++);
    }
    while (true)
    {
        f = !f;
        mCond.notify_one();
        Sleep(1000);
    }

    return 0;
}
  • 写回答

1条回答 默认 最新

  • 关注
    #include <iostream>
    #include <mutex>
    #include <thread>
    #include <vector>
    #include <windows.h>
    
    using std::condition_variable;
    using std::mutex;
    using std::thread;
    
    mutex mymutex;
    condition_variable mCond;
    bool flag = false;
    
    class Thread
    { // 自定义线程类
      public:
        using CallBackFunc = void (*)(void *);
        thread::id threadId;
    
        auto start(void *arg) -> bool;
        auto detach() -> bool;
        auto join() -> bool;
        void handle(void *arg)
        {
            callBackF(arg);
        };
    
        Thread()
            : mArg(nullptr)
            , mIsStart(false)
            , mIsDetach(false){};
    
        explicit Thread(CallBackFunc callBackFunc)
            : mArg(nullptr)
            , mIsStart(false)
            , mIsDetach(false)
            , callBackF(callBackFunc){};
    
        ~Thread();
    
      private:
        void run(void *arg);
        auto threadRun(void * /*arg*/) -> void *;
        void *mArg;
        bool mIsStart;
        bool mIsDetach;
        thread mThreadId;
        CallBackFunc callBackF;
    };
    
    auto Thread::start(void *arg) -> bool
    {
        mArg = arg;
        mThreadId = thread(&Thread::threadRun, this, this);
        mIsStart = true;
        threadId = std::this_thread::get_id();
        return true;
    }
    
    auto Thread::detach() -> bool
    {
        if (!mIsStart)
        {
            return false;
        }
        if (mIsDetach)
        {
            return true;
        }
        mThreadId.detach();
        mIsDetach = true;
        return true;
    }
    
    auto Thread::join() -> bool
    {
        if (!mIsStart || mIsDetach)
        {
            return false;
        }
        mThreadId.join();
        return true;
    }
    
    Thread::~Thread()
    {
        if (mIsStart && !mIsDetach)
        {
            detach();
            printf("detach");
        }
    }
    
    auto Thread::threadRun(void *arg) -> void *
    {
        Thread *t = static_cast<Thread *>(arg);
        t->run(t->mArg);
        return nullptr;
    }
    
    void Thread::run(void *arg)
    {
        handle(arg);
    }
    
    void action1(void *arg)
    {
        std::unique_lock<mutex> sb(mymutex);
        mCond.wait(sb, []() -> bool { return !flag; });
        int *x = static_cast<int *>(arg);
        std::cout << "thread id: " << std::this_thread::get_id() << " x: " << x
                  << std::endl;
    }
    
    int main()
    {
        int x = 1;
        std::vector<Thread *> v;
        for (int i = 0; i < 5; i++)
        {
            v.push_back(new Thread(action1));
            v[i]->start((void *)&++x);
        }
        for (int i = 0; i != 10; ++i)
        {
            flag = !flag;
            mCond.notify_one();
            Sleep(1000);
        }
        for (int i = 0; i != 5; ++i)
        {
            delete v[i];
        }
    
        return 0;
    }
    
    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月12日

悬赏问题

  • ¥15 matlab数据降噪处理,提高数据的可信度,确保峰值信号的不损失?
  • ¥15 怎么看我在bios每次修改的日志
  • ¥15 python+mysql图书管理系统
  • ¥15 Questasim Error: (vcom-13)
  • ¥15 船舶旋回实验matlab
  • ¥30 SQL 数组,游标,递归覆盖原值
  • ¥15 为什么我的数据接收的那么慢呀有没有完整的 hal 库并 代码呀有的话能不能发我一份并且我用 printf 函数显示处理之后的数据,用 debug 就不能运行了呢
  • ¥20 gitlab 中文路径,无法下载
  • ¥15 用动态规划算法均分纸牌
  • ¥30 udp socket,bind 0.0.0.0 ,如何自动选取用户访问的服务器IP来回复数据