我不确定标题是否能准确反映我的问题,但这是我能做到的最好的了。我正在尝试在pthreads中实现一个“工作线程”模型。我想要从“main”函数生成一组线程,然后“main”线程将任务委派给工作线程并等待所有线程完成后再分配下一个任务(实际上,要求像CUDA编程模型一样在CPU上排列线程块,但与当前问题无关)。"job"数组用于指示每个线程的工作类型。目前,我使用信号量来实现这一点,但会导致繁忙等待。我正在寻找方法使线程在不断轮询的情况下仅在需要时进入睡眠并唤醒。
每个线程执行的函数
主要功能如下。
这种实现的问题在于
每个线程执行的函数
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();
}
这种实现的问题在于
main
线程一直忙于等待所有工作线程完成,并且工作线程也不断轮询任务数组以检查是否有新任务。当线程需要休眠并在需要时唤醒时,是否有更好的方法,类似于信号处理程序和使用pthread_kill()
,但这种方法有点混乱,需要单独的信号处理程序。