gpt4 book ai didi

c - 唤醒单个线程而不是在 pthreads 中忙于等待

转载 作者:太空狗 更新时间:2023-10-29 15:36:36 30 4
gpt4 key购买 nike

我不确定标题是否反射(reflect)了我在这里的要求,但如果没有很长的标题,那是我能做的最好的。我正在尝试在 pthreads 中实现一个 worker thread 模型。我想从 main 函数中生成一组线程,然后 main 线程将作业委托(delegate)给 worker 并等待所有线程完成,然后再为它们分配下一个作业(实际上,要求是将线程安排在一个非常像 CUDA 编程模型但在 CPU 上的 block 中。虽然它与当前问题无关)。 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() 唤醒时,是否有更好的方法来执行此操作,但使用单独的信号处理程序有点困惑。

最佳答案

您可以使用 conditional variable使线程进入休眠状态直到发出信号。

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();
}

关于c - 唤醒单个线程而不是在 pthreads 中忙于等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9488185/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com