在pthread中醒来单个线程,而不是忙等待的 [英] Waking up individual threads instead of busy wait in pthreads
问题描述
我不知道如果标题反映了我在问什么在这里但这就是最好没有一个非常龙头衔,我可以做的。在的pthreads我试图实施
。我想产卵从工作线程
模式主
函数一组线程,其后主
线程代表工作的工人,等待所有线程分配它们的下一个作业之前完成(实际上,要求是安排很像CUDA编程模型,但在CPU中的块的线程。虽然它不是当前问题相关)。在工作
阵列用于指示作业的每个线程的类型。目前,我实现了这一点使用信号灯其中规定忙等待。我在寻找各种方法来让这个线程去睡觉,醒来时只需要他们,而不是不断地轮询
I'm not sure if the title reflects what I'm asking here but thats best I can do without a very loong title. I'm trying to implement a worker thread
model in pthreads
. I want to spawn a set of threads from the main
function and thereafter the main
thread delegates the job to the worker and wait for all threads to complete before assigning them the next job (Actually, the requirement is to arrange the thread in a block much like CUDA programming model but on the CPU. Although its not relevant to the current question). The job
array is used to indicate the type of job to each thread. Currently, I've implemented this using semaphores which imposes a busy wait. I'm looking for ways to make it so that the threads go to sleep and wake up only when they are required rather than polling continuously.
每个线程执行的功能。
volatile int jobs[MAX_THREADS]; // global job indicator array
sem_t semaphore; // semaphore to indicate completion
thread_execute(void *args)
{
tid = get_id(args);
while(jobs[tid] != -1)
{
if(jobs[tid] == 0) continue; // no job
if(jobs[tid] == JOBS_1)
{
jobs1();
jobs[tid] = 0; // go back to idle state
sem_post(&semapahore);
}
if(jobs[tid] == JOBS_2)
{
jobs2();
jobs[tid] = 0; // go back to idle state
sem_post(&semapahore);
}
}
pthread_exit(NULL);
}
主要功能如下:
int main()
{
sem_init(&semaphore, 0, 0);
jobs[0...MAX_THREADS] = 0;
spawn_threads();
// Dispatch first job
jobs[0...MAX_THREADS] = JOBS_1;
int semvalue = 0;
while (semvalue < MAX_THREADS) // Wait till all threads increment the semaphore
sem_getvalue(&sempaphore, &semvalue);
sem_init(&semaphore, 0, 0); // Init semaphore back to 0 for the next job
// I'm actually using diff. semaphores for diff. jobs
jobs[0...MAX_THREADS] = JOBS_2;
while (semvalue < MAX_THREADS)
sem_getvalue(&sempaphore, &semvalue);
jobs[0...MAX_THREADS] = -1; // No more jobs
pthread_join();
}
这个实现的问题是,主
线程繁忙等待所有工作线程来完成和工作线程也在不断轮询作业阵列检查新工作。有没有更好的办法做到这一点时,线程进入睡眠状态,并沿着葛处理程序,并使用 pthread_kill()
的线需要的时候醒来,但它是一种凌乱一个独立的信号处理程序。
The problem with this implementation is that the main
thread is busy waiting for all worker threads to finish and worker threads are also constantly polling the jobs array to check for a new job. Is there a better way to do this when threads go to sleep and wake up when needed along the lines of a singal handler and using pthread_kill()
but it is kind of messy with a separate signal handler.
推荐答案
您可以使用的条件变量使线程进入睡眠状态,直到信号。
You can use a conditional variable to make the threads go to sleep until signaled.
volatile int jobs[MAX_THREADS]; // global job indicator array
pthread_cond_t th_cond; // threads wait on this
pthread_mutex_t th_mutex; // mutex to protect the signal
int busyThreads = MAX_THREADS;
pthread_cond_t m_cond; // main thread waits on this
pthread_mutex_t m_mutex; // mutex to protect main signal
thread_execute(void *args)
{
tid = get_id(args);
while(jobs[tid] != -1)
{
if(jobs[tid] == 0) continue; // no job
if(jobs[tid] == JOBS_1)
{
jobs1();
jobs[tid] = 0; // go back to idle state
pthread_mutex_lock(&th_mutex);
pthread_mutex_lock(&m_mutex);
--busyThreads; // one less worker
pthread_cond_signal(&m_cond); // signal main to check progress
pthread_mutex_unlock(&m_mutex);
pthread_cond_wait(&th_cond, &th_mutex); // wait for next job
pthread_mutex_unlock(&th_mutex);
}
if(jobs[tid] == JOBS_2)
{
jobs2();
jobs[tid] = 0; // go back to idle state
pthread_mutex_lock(&th_mutex);
--busyThreads;
pthread_cond_wait(&th_cond, &th_mutex);
pthread_mutex_unlock(&th_mutex);
}
}
pthread_exit(NULL);
}
然后主:
int main()
{
sem_init(&semaphore, 0, 0);
jobs[0...MAX_THREADS] = 0;
spawn_threads();
// Dispatch first job
jobs[0...MAX_THREADS] = JOBS_1;
int semvalue = 0;
pthread_mutex_lock(&m_mutex);
while(busyThreads > 0) // check number of active workers
pthread_cond_wait(&m_cond, &m_mutex);
pthread_mutex_unlock(&m_mutex);
busyThreads = MAX_THREADS;
pthread_mutex_lock(&th_mutex);
pthread_cond_broadcast(&th_cond); // signal all workers to resume
pthread_mutex_unlock(&th_mutex);
// same for JOBS_2;
jobs[0...MAX_THREADS] = -1; // No more jobs
pthread_join();
}
这篇关于在pthread中醒来单个线程,而不是忙等待的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!