C ++持有许多线程

时间:2013-08-14 17:48:55

标签: c++ windows multithreading semaphore

我是C ++(在Windows上)和线程的新手,我正在尝试使用互斥锁,信号量和事件找到解决问题的方法。 我正在尝试使用构造函数和名为Enter的方法创建一个Barrier类。具有唯一方法Enter的Barrier类应该阻止任何进入它的线程,直到许多线程已经到达该方法。在构造函数中收到的等待它的线程数。 我的问题是如何使用锁来创建该效果?我需要的是像反向信号量一样的东西,它保持线程直到达到计数,而不是像常规信号量工作那样让线程进入到计数之前。 关于如何解决这个问题的任何想法都会很棒。 谢谢, Netanel。

3 个答案:

答案 0 :(得分:1)

也许:

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

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

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

答案 1 :(得分:1)

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

以下是一个例子:

我声明了25个线程并使用WorkerThread函数启动它们。

我正在检查阻止/取消单击线程的条件是该部分中的线程数是否小于2。 (我添加了一些断言来证明我的coode做了什么)。

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

我还为cout添加了一个互斥锁,以获得干净的消息。     #包括     #包括     #包括     #包括     #包括     #包括     #include / *断言* /     使用namespace 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;
}

希望有所帮助,告诉我您是否有任何问题,我可以发表评论或更改我的代码。

答案 2 :(得分:0)

伪代码轮廓可能如下所示:

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).
    }
}