简体   繁体   English

C ++拥有多个线程

[英]C++ Holding a number of threads

I'm new to C++ (on Windows) and threading and I'm currently trying to find a solution to my problem using mutexes, semaphores and events. 我是C ++(在Windows上)和线程技术的新手,我目前正在尝试使用互斥量,信号量和事件为我的问题找到解决方案。 I'm trying to create a Barrier class with a constructor and a method called Enter. 我正在尝试使用构造函数和名为Enter的方法创建Barrier类。 The class Barrier with it's only method Enter is supposed to hold off any thread that enters it, until a number of thread have reached that method. 具有唯一方法Enter的类Barrier应该阻止所有进入它的线程,直到有多个线程到达该方法为止。 The number of thread to wait for it recieved at the contructor. 在构造器上接收到等待的线程数。 My problem is how do I use the locks to create that effect? 我的问题是如何使用锁来创建效果? what I need is something like a reversed semaphore, that holds threads until a count has been reached and not like the regular semaphore works that lets threads in until a count is reached. 我需要的是像反转信号量这样的东西,它保持线程直到达到计数为止,而不像常规信号量那样使线程进入直到达到计数为止。 Any ideas as to how to go about this would be great. 关于如何做到这一点的任何想法都很棒。 Thanks, Netanel. 谢谢,Netanel。

Maybe: 也许:

In the ctor, store the limit count and create an empty semaphore. 在ctor中,存储限制计数并创建一个空的信号灯。

When a thread calls Enter, lock a mutex first so you can twiddle inside safely. 当线程调用Enter时,请先锁定互斥锁,以便您可以安全地在其中旋转。 Inc a thread count toward the limit count. 将线程数增加到限制数。 If the limit has not yet been reached, release the mutex and wait on the semaphore. 如果尚未达到限制,请释放互斥锁并等待信号量。 If the limit is reached, signal the semaphore[limit-1] times in a loop, zero the thread count, (ready for next time), release the mutex and return from Enter(). 如果达到限制,则循环发送semaphore [limit-1]信号,将线程计数清零(准备下一次),释放互斥锁并从Enter()返回。 Any threads that were waiting on the semaphore, and are now ready/running, should just return from their 'Enter' call. 正在等待信号量且现在已就绪/正在运行的任何线程都应从其“ Enter”调用中返回。

The mutex prevents any released thread that loops around from 'getting in again' until all the threads that called 'Enter' and waited have been set running and the barrier is reset. 互斥体会阻止循环释放的所有线程“再次进入”,直到所有名为“ Enter”并等待的线程都已设置为运行并且重置了屏障。

You can implement it with condition variable. 您可以使用条件变量来实现它。

Here is an example: 这是一个例子:

I declare 25 threads and launch them doing the WorkerThread function. 我声明25个线程,并通过WorkerThread函数启动它们。

The condition I am checking to block/unblick the threads is whether the number of threads in the section is less than 2. (I have added some asserts to prove what my coode does). 我要检查的阻止/取消模糊线程的条件是该部分中的线程数是否少于2。(我添加了一些断言来证明我的库德做了什么)。

My code is simply sleeping in the critical section and after I decrease the number of threads in the critical section. 我的代码只是在临界区中休眠,而在减少临界区中的线程数之后。

I also added a mutex for the cout to have clean messages. 我还添加了一个互斥体以使cout具有干净的消息。 #include #include #include #include #include #include #include /* assert */ using namespace std; #include #include #include #include #include #include #include #include / * assert * /使用命名空间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;
}

Hope that helps, tell me if you have any questions, I can comment or change my code. 希望对您有所帮助,如果有任何疑问,请告诉我,我可以注释或更改代码。

Pseudocode outline might look like this: 伪代码大纲可能如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM