栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

线程等待父线程

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

线程等待父线程

您需要的是条件变量。
所有工作线程都调用wait(),这将暂停它们。

然后,父线程将工作项放在队列中,并在条件变量上调用signal。这将唤醒正在hibernate的一个线程。它可以从队列中删除该作业,然后执行该作业,然后在条件变量上调用wait以返回睡眠状态。

尝试:

#include <pthread.h>#include <memory>#include <list>// Use RAII to do the lock/unlockstruct MutexLock{    MutexLock(pthread_mutex_t& m) : mutex(m)    { pthread_mutex_lock(&mutex); }    ~MutexLock()          { pthread_mutex_unlock(&mutex); }    private:        pthread_mutex_t&    mutex;};// The base class of all work we want to do.struct Job{    virtual void doWork()  = 0;};// pthreads is a C library the call back must be a C function.extern "C" void* threadPoolThreadStart(void*);// The very basre minimal part of a thread pool// It does not create the workers. You need to create the work threads// then make them call workerStart(). I leave that as an exercise for you.class ThreadPool{    public:         ThreadPool(unsigned int threadCount=1);        ~ThreadPool();        void addWork(std::auto_ptr<Job> job);    private:        friend void* threadPoolThreadStart(void*);        void workerStart();        std::auto_ptr<Job>  getJob();        bool     finished;   // Threads will re-wait while this is true.        pthread_mutex_t     mutex;      // A lock so that we can sequence accesses.        pthread_cond_t      cond;       // The condition variable that is used to hold worker threads.        std::list<Job*>     workQueue;  // A queue of jobs.        std::vector<pthread_t>threads;};// Create the thread poolThreadPool::ThreadPool(int unsigned threadCount)    : finished(false)    , threads(threadCount){    // If we fail creating either pthread object than throw a fit.    if (pthread_mutex_init(&mutex, NULL) != 0)    {   throw int(1);    }    if (pthread_cond_init(&cond, NULL) != 0)    {        pthread_mutex_destroy(&mutex);        throw int(2);    }    for(unsigned int loop=0; loop < threadCount;++loop)    {       if (pthread_create(threads[loop], NULL, threadPoolThreadStart, this) != 0)       { // One thread failed: clean up for(unsigned int kill = loop -1; kill < loop ;--kill) {     pthread_kill(threads[kill], 9); } throw int(3);       }    }}// Cleanup any left overs.// Note. This does not deal with worker threads.//       You need to add a method to flush all worker threads//       out of this pobject before you let the destructor destroy it.ThreadPool::~ThreadPool(){    finished = true;    for(std::vector<pthread_t>::iterator loop = threads.begin();loop != threads.end(); ++loop)    {        // Send enough signals to free all threads.        pthread_cond_signal(&cond);    }    for(std::vector<pthread_t>::iterator loop = threads.begin();loop != threads.end(); ++loop)    {        // Wait for all threads to exit (they will as finished is true and        //         we sent enough signals to make sure        //         they are running).        void*  result;        pthread_join(*loop, &result);    }    // Destroy the pthread objects.    pthread_cond_destroy(&cond);    pthread_mutex_destroy(&mutex);    // Delete all re-maining jobs.    // Notice how we took ownership of the jobs.    for(std::list<Job*>::const_iterator loop = workQueue.begin(); loop != workQueue.end();++loop)    {        delete *loop;    }}// Add a new job to the queue// Signal the condition variable. This will flush a waiting worker// otherwise the job will wait for a worker to finish processing its current job.void ThreadPool::addWork(std::auto_ptr<Job> job){    MutexLock  lock(mutex);    workQueue.push_back(job.release());    pthread_cond_signal(&cond);}// Start a thread.// Make sure no exceptions escape as that is bad.void* threadPoolThreadStart(void* data){    ThreadPool* pool = reinterpret_cast<ThreadPool*>(workerStart);    try    {        pool->workerStart();    }    catch(...){}    return NULL;}// This is the main worker loop.void ThreadPool::workerStart(){    while(!finished)    {        std::auto_ptr<Job>    job    = getJob();        if (job.get() != NULL)        { job->doWork();        }    }}// The workers come here to get a job.// If there are non in the queue they are suspended waiting on cond// until a new job is added above.std::auto_ptr<Job> ThreadPool::getJob(){    MutexLock  lock(mutex);    while((workQueue.empty()) && (!finished))    {        pthread_cond_wait(&cond, &mutex);        // The wait releases the mutex lock and suspends the thread (until a signal).        // When a thread wakes up it is help until it can acquire the mutex so when we        // get here the mutex is again locked.        //        // Note: You must use while() here. This is because of the situation.        //   Two workers:  Worker A processing job A.        //      Worker B suspended on condition variable.        //   Parent adds a new job and calls signal.        //   This wakes up thread B. But it is possible for Worker A to finish its        //   work and lock the mutex before the Worker B is released from the above call.        //        //   If that happens then Worker A will see that the queue is not empty        //   and grab the work item in the queue and start processing. Worker B will        //   then lock the mutext and proceed here. If the above is not a while then        //   it would try and remove an item from an empty queue. With a while it sees        //   that the queue is empty and re-suspends on the condition variable above.    }    std::auto_ptr<Job>  result;    if (!finished)    {    result.reset(workQueue.front());         workQueue.pop_front();    }    return result;}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/402665.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号