2011-02-19 233 views
0

基本上我的程序有2套线程,工人和工作。每个作业都有一个到达时间,然后将其推送到队列中。多线程程序

对于服务器,我希望他们不断地在队列中寻找工作,一旦队列中有工作,只有1名工作人员将其关闭并完成其工作。

主要是,首先创建所有的工作线程,然后创建并同步作业线程(每个工作线程推入队列中的东西)。由于工作线程有时在同一时间完成任务,或者没有在正确的时间将工作推送到队列中,所以我无法获得正确的时间安排(即:到达时间3的工作在到达时间之前被推送到工作中2)。 我该如何使用信号量和/或互斥锁来做到这一点?

我试图把一个互斥体的工人功能,但我真的没有互斥锁/信号灯办理好..

任何想法,将不胜感激。

谢谢!

+0

你的术语是痛苦的。用server = worker,client = job,client thread = server重写。 – 2011-02-19 01:27:16

+2

呃。除了使用`std :: cout`,这是纯粹的C代码。你知道C++不仅仅是一个C插件吗?如果你非常喜欢C语言,甚至可以在C++不需要它的地方使用`struct`关键字,但是C可以,那么为什么不放弃流以支持`printf()`等等,并且使用纯C呢?因为它使得C群使用流而使C不高兴,而使用C的C++群体除了流之外。 – sbi 2011-02-19 01:43:20

回答

0

问题是,你的服务器正在做三个非原子队列操作(空,然后前,然后弹出),没有同步,以确保其他线程不交错其操作。在调用Q.mpty之前,您需要先获取互斥锁或信号量,然后在调用Q.pop后释放它,以确保空/前/三重奏以原子方式完成。如果Q.empty失败,则还需要确保正确释放mutux

1

answer复制到one of my earlier questions。我的问题涉及Win32线程,但描述的概念与pthread几乎相同。

  1. 在您的队列中使用信号量来指示是否有元素准备好进行处理。
  2. 你添加一个项目时,都会打电话sem_post()递增与信号
  3. 在你的线程进程相关联在循环计数,在你的信号灯对象

这里的句柄调用sem_wait()是一个教程对于POSIX Semaphores

但首先像其他人说的,你必须使Q线程安全。

void *func(void *newWorker) { 
    struct workerType* worker = (struct workerType*) newWorker; 
    while(numServed < maxJobs) { 
     //if(!Q.empty()) { 
     // No need to ask if Q is empty. 
     // If a thread passes the sem_wait function 
     // there has to be at least one job in the Q 
     sem_wait(&semaphore); 
     pthread_mutex_lock(&mutex); 
     struct jobType* job = Q.front(); 
     numServed++; 
     cout << job->jobNum << " was served by " << worker->workerNum << endl; 
     Q.pop(); 
     pthread_mutex_unlock(&mutex); 
     //sleep(worker->runTime); No need to sleep also   
     //} 
    } 
} 


void *job(void *jobdata) { 
    struct jobType *job = (struct jobType*) jobdata; 
    //sleep(job->arrivtime); 
    pthread_mutex_lock(&mutex); 
    Q.push(job); 
    pthread_mutex_unlock(&mutex); 
    sem_post(&semaphore); 
    // Inform the workers that another job is pushed. 
} 
1

Q推Q弹出操作需要原子,即(是关键部分)。把它放在一个Mutex获取和Mutex发布之下。这应该为你做。

检查posix线程教程以了解互斥锁的获取和释放。我用这个PTHREAD TUTORIAL