条件变量同步

发布时间 2023-11-13 11:07:15作者: 开花石头
#include <thread>
#include <iostream>
#include "glock.h"
#include "mylogger.h"
extern std::mutex g_mtx;
extern std::mutex g_mtx_main;
extern std::condition_variable cvMain;
extern std::condition_variable cvWorker;
extern int g_numThreads;

int nDevice = 3;

bool allThreadsCompleted = false;

void controlThreadFunction(int id, int casesize, int devicesize, bool bstop = false) {
    std::cout << "contorl Thread " << id << " is running." << std::endl;

    int index = 0;
    int nCount = casesize;
    while (!bstop && index++ < casesize) {
        {
            std::unique_lock<std::mutex> lock(g_mtx);

            // 设置工作线程数量
            g_numThreads = devicesize;
            // 重置标志
            allThreadsCompleted = false;
        }

        // 主线程等待所有工作线程完成
        Logger::getInstance().logToConsole("controlthread:main thread wait workthread");
        {
            std::unique_lock<std::mutex> lock(g_mtx);
            cvMain.wait(lock, [] { return allThreadsCompleted; });
        }

  

  // 短暂的延时,留出时间确保所有工作线程都进入等待状态
  std::this_thread::sleep_for(std::chrono::milliseconds(1000))


        // 主线程通知所有工作线程可以继续
        Logger::getInstance().logToConsole("controlthread:main thread notify all sub-work thread");
        cvWorker.notify_all();
    }

    Logger::getInstance().logToConsole("controlthread:exit");

}

void workerThreadFunction(int id, int casesize, int devicesize, bool bstop = false) {
    int nCount = casesize;
    std::this_thread::sleep_for(std::chrono::seconds(2));
    for (int index = 0; index < nCount; ++index) {
        Logger::getInstance().logToConsole("workerthread:.......do somethings ...." + std::to_string(index) + "_thread:" + std::to_string(id));

        {
            std::lock_guard<std::mutex> lock(g_mtx);
            g_numThreads--;
   // 设置标志表示所有工作线程完成
            if (g_numThreads == 0) {
                allThreadsCompleted = true;
                cvMain.notify_one();  // 通知主线程
                Logger::getInstance().logToConsole("workerthread:.......notify main thread " + std::to_string(index) + "_thread:" + std::to_string(id));
            }
        }
        Logger::getInstance().logToConsole("workerthread:.......wait main thread notify " + std::to_string(index) + "_thread:" + std::to_string(id));

        // 进入等待,等待主线程通知
        {
            std::unique_lock<std::mutex> lock(g_mtx);
            cvWorker.wait(lock);
        }
    }

    Logger::getInstance().logToConsole("workthread:exit");
}
 
 
int main() {

    //Logger& ins = Logger::getInstance();

    //nDevice
    //std::thread threads[3];

    g_numThreads = 3;

    std::thread control_thread = std::thread(controlThreadFunction, 1+ nDevice, 3, nDevice,false);
    std::vector<std::thread> threads;

    for (int i = 0; i < nDevice; ++i) {
        threads.emplace_back(workerThreadFunction, i + 1, 3, nDevice, false);
    }

    //for (int i = 0; i < nDevice; ++i) {
    //    threads[i] = std::thread(workerThreadFunction, i + 1,2, nDevice,false);
    //}


    control_thread.join();

    for (int i = 0; i < nDevice; ++i) {
        threads[i].join();
    }


    std::cout << "All threads have finished." << std::endl;
}