C++ C++;有许多线的

C++ C++;有许多线的,c++,windows,multithreading,semaphore,C++,Windows,Multithreading,Semaphore,伪代码大纲可能如下所示: void Enter() { Increment counter (atomically or with mutex) if(counter >= desired_count) { condition_met = true; (protected if bool writes aren't atomic on your architecture) cond_broadcast(blocking_cond_va

伪代码大纲可能如下所示:

void Enter()
{
    Increment counter (atomically or with mutex)
    if(counter >= desired_count)
    {
        condition_met = true; (protected if bool writes aren't atomic on your architecture)
        cond_broadcast(blocking_cond_var);
    }
    else
    {
        Do a normal cond_wait loop-plus-predicate-check (waiting for the broadcast and checking condition_met each iteration to protect for spurious wakeups).
    }
}
也许:

在ctor中,存储限制计数并创建一个空信号量

当一个线程调用Enter时,首先锁定一个互斥锁,这样你就可以在里面安全地旋转。将线程计数增加到限制计数。如果尚未达到限制,请释放互斥并等待信号量。如果达到限制,则在循环中向信号量[limit-1]发送信号数次,将线程计数归零(准备下次),释放互斥锁并从Enter()返回。任何正在等待信号量的线程,现在已经准备好/正在运行,应该从他们的“Enter”调用返回


互斥锁防止任何循环的已释放线程“再次进入”,直到调用“Enter”并等待的所有线程都已设置为运行且屏障已重置。

您可以使用条件变量实现它

以下是一个例子:

我声明了25个线程,并通过WorkerThread函数启动它们

我正在检查阻止/取消单击线程的条件是节中的线程数是否小于2。 (我添加了一些断言以证明我的coode所做的事情)

我的代码只是在关键部分休眠,在我减少了关键部分的线程数量之后

我还为cout添加了一个互斥锁,以使cout具有干净的消息。 #包括 #包括 #包括 #包括 #包括 #包括 #包括/*断言*/ 使用名称空间std

std::mutex m;
atomic<int> NumThreadsInCritialSection=0;
int MaxNumberThreadsInSection=2;
std::condition_variable cv;

mutex coutMutex;

 int WorkerThread()
{
    // Wait until main() sends data
    {
        std::unique_lock<std::mutex> lk(m);
        cv.wait(lk, []{return NumThreadsInCritialSection<MaxNumberThreadsInSection;});
    }
    assert (NumThreadsInCritialSection<MaxNumberThreadsInSection);
    assert (NumThreadsInCritialSection>=0);
    NumThreadsInCritialSection++;
    {
        std::unique_lock<std::mutex> lk(coutMutex);
        cout<<"NumThreadsInCritialSection= "<<NumThreadsInCritialSection<<endl;
    }

    std::this_thread::sleep_for(std::chrono::seconds(5));
    NumThreadsInCritialSection--;
    {
        std::unique_lock<std::mutex> lk(coutMutex);
        cout<<"NumThreadsInCritialSection= "<<NumThreadsInCritialSection<<endl;
    }

    cv.notify_one();
    return 0;
}

int main()
{
    vector<thread> vWorkers;
    for (int i=0;i<25;++i)
    {
        vWorkers.push_back(thread(WorkerThread));
    }

    for (auto j=vWorkers.begin(); j!=vWorkers.end(); ++j)
    {
        j->join();
    }
    return 0;
}
std::mutexm;
原子NumThreadsInCritialSection=0;
int MaxNumberThreadsInSection=2;
std::条件变量cv;
互斥coutMutex;
int-WorkerThread()
{
//等待main()发送数据
{
std::唯一锁lk(m);

cv.等待(lk,[]{return numthreadsincritialsection你想使用c++11线程还是WinAPI?@dan-我在使用WinAPI我考虑过类似的事情。我的问题是在释放互斥锁和等待信号量之间会发生什么。在那个时候,任何事情都可能发生,比如所需的线程数和释放导致互斥锁的障碍在线程中等待下一个组,即使它是第一个到达的…我不确定您是否只需要一个Enter()就可以实现您想要的。如果您让每个线程在离开受保护区域(或正要循环回来)时调用一个Leave()函数然后,你可能会建立一个两阶段的障碍,这将工作,因为你想它。