我正在使用 pthreads 和信号量,并且我正在尝试找出如何向特定线程发出信号。
我想用特定条件发出信号的线程将是在队列头部等待的线程。
我的 semaphore.h 文件的主要部分是:
struct entry_thread {
int threadID;
SIMPLEQ_ENTRY(entry_thread) next;
} *np;
struct semaphore {
int count;
int headThreadID;
pthread_mutex_t mutex;
pthread_cond_t flag;
SIMPLEQ_HEAD(queuehead, entry_thread) head;
};
typedef struct semaphore semaphore_t;
我的 semaphore.c 文件的相关部分是:
void down( semaphore_t* sem )
{
pthread_mutex_lock( &sem->mutex );
while ( sem->count <= 0)
{
// First check if queue is empty, if so, set a new headThreadID
if (SIMPLEQ_EMPTY( &(sem->head) ))
{
sem->headThreadID = pthread_self();
}
np = malloc( sizeof( struct entry_thread ) );
np->threadID = pthread_self();
SIMPLEQ_INSERT_TAIL( &(sem->head), np, next);
pthread_cond_wait( &sem->flag, &sem->mutex );
}
sem->count--;
pthread_mutex_unlock( &sem->mutex );
}
void up( semaphore_t* sem )
{
pthread_mutex_lock( &sem->mutex );
sem->count++;
if ( sem->count == 1 )
{
// Get the head of the semaphore's queue
SIMPLEQ_REMOVE_HEAD( &(sem->head), (np = SIMPLEQ_FIRST(&(sem->head))), next );
/* I WANT TO ONLY SIGNAL THE HEAD THREAD!!! */
pthread_cond_signal( &sem->flag );
/* THE ABOVE SIGNALS A RANDOM SINGLE THREAD */
free( np );
}
pthread_mutex_unlock( &sem->mutex );
}
所以我的问题是,即使我可以获得线程的 ID,我也需要能够向该线程发出信号,表明它正在等待的条件已更改,并且它可以再次测试信号量。任何建议将不胜感激。
第一个建议应该是,始终检查调用锁定互斥体以及条件 API 函数的返回值。
虽然一切正常,省略返回值检查工作正常,但当出现问题时,整个系统就会崩溃,导致无法调试或追踪问题的根源。
pthread_cond_signal
唤醒随机单线程背后的想法是:在多线程应用程序中,您的任务不依赖于执行顺序。当您有 X 个线程等待相同的条件时,假定在发出条件信号时它们中的任何一个都可以运行。
一般来说,不同的线程做不同的事情,应该在不同的条件下等待。
您的代码似乎只将一个线程插入队列,它并不是真正的队列。
您对
pthread_cond_wait
的使用不包括检查(有意义的)谓词,如果您不确定为什么需要谓词,请做一些研究。如果谓词应该是 while
那么我认为您的代码中存在逻辑错误。
一旦您的队列正确填充了等待 CPU 时间的所有线程,您就可以将
pthread_cond_signal
交换为 pthread_cond_broadcast
并将 pthread_cond_wait
的谓词设为一个标志,以确定当前线程是否是正在调度的线程。我假设您需要唤醒以正确顺序等待的其他线程,以某种方式......
这不是我能想象的调度程序的最佳实现,但它接近您的尝试。您应该让它工作,然后看看是否可以通过确定它的性能特征是什么以及它们应该是什么来改进它。