使用条件

时间:2015-11-01 04:10:57

标签: c unix pthreads semaphore openbsd

我正在使用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,我需要能够通知该线程它正在等待的条件已经改变,它可以再次测试信号量。任何建议都将不胜感激。

1 个答案:

答案 0 :(得分:0)

第一点建议应该是,总是检查来自锁定互斥锁的调用的返回值,以及条件API函数。

虽然一切正常,但省略返回值检查可以正常工作,但是当它出错时,整个系统会以一种无法调试或跟踪问题根源的方式降低。

pthread_cond_signal唤醒随机单线程背后的想法是:在多线程应用程序中,您的任务不依赖于执行顺序。当X线程在相同条件下等待时,假定在发出条件信号时它们中的任何一个都可以运行。

一般来说,做不同事情的不同线程应该在不同条件下等待。

您的代码似乎只是在队列中插入一个线程,它实际上并不是一个队列。

您对pthread_cond_wait的使用不包括检查(有意义的)谓词,如果您不确定为什么需要谓词,请进行一些研究。如果谓词应该是while,那么我认为你的代码中存在逻辑错误。

如果我对您的代码的工作方式完全错误,那么因为大部分代码都缺失了:https://stackoverflow.com/help/mcve

正在使用等待cpu时间的所有线程正确填充队列后,您可以将pthread_cond_signal交换为pthread_cond_broadcast并为pthread_cond_wait生成一个标记,以确定是否当前线程是正在调度的线程。我假设您需要唤醒正在等待的其他线程,其中一些如何......

这不是我可以想象的调度程序的最佳实现,但它接近您的尝试。你应该让它运作起来,然后看看你是否可以通过确定它的性能特征是什么以及它们应该是什么来改进它。

由于这是一项任务,我不打算为你编写代码,这对你没用。