pthreads:由快速重新锁定引起的线程饥饿

sci*_*ete 9 c++ multithreading pthreads

我有两个线程,一个在紧密循环中工作,另一个偶尔需要与第一个执行同步:

// thread 1
while(1)
{
    lock(work);
    // perform work
    unlock(work);
}

// thread 2
while(1)
{
    // unrelated work that takes a while
    lock(work);
    // synchronizing step
    unlock(work);
}
Run Code Online (Sandbox Code Playgroud)

我的意图是,通过获取锁,线程2可以有效地暂停线程1并执行必要的同步.线程1还可以通过解锁来提供暂停,如果线程2没有等待锁定,则重新锁定并返回工作.

我遇到的问题是互斥是不公平的,所以线程1快速重新锁定互斥锁并使线程2饿死.我试图使用pthread_yield,到目前为止似乎运行正常,但我不确定它是否会起作用所有系统/核心数量.有没有办法保证线程1总能屈服于线程2,即使在多核系统上也是如此?

处理此同步过程的最有效方法是什么?

caf*_*caf 6

您可以在这些行上在pthreads互斥锁之上构建FIFO"票证锁定":

#include <pthread.h>

typedef struct ticket_lock {
    pthread_cond_t cond;
    pthread_mutex_t mutex;
    unsigned long queue_head, queue_tail;
} ticket_lock_t;

#define TICKET_LOCK_INITIALIZER { PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER }

void ticket_lock(ticket_lock_t *ticket)
{
    unsigned long queue_me;

    pthread_mutex_lock(&ticket->mutex);
    queue_me = ticket->queue_tail++;
    while (queue_me != ticket->queue_head)
    {
        pthread_cond_wait(&ticket->cond, &ticket->mutex);
    }
    pthread_mutex_unlock(&ticket->mutex);
}

void ticket_unlock(ticket_lock_t *ticket)
{
    pthread_mutex_lock(&ticket->mutex);
    ticket->queue_head++;
    pthread_cond_broadcast(&ticket->cond);
    pthread_mutex_unlock(&ticket->mutex);
}
Run Code Online (Sandbox Code Playgroud)

在这种方案下,当线程在受到故障锁定保护的关键部分内时,不保留低级pthreads互斥锁,允许其他线程加入队列.

  • @lornova:不.`pthread_cond_wait()`是POSIX列出的函数之一*["函数(即)使内存与其他线程同步."](http://pubs.opengroup.org/onlinepubs/9699919799 /basedefs/V1_chap04.html#tag_04_12)*.编译器无法在这些函数调用之间缓存值. (2认同)

Ser*_*lov 5

在您的情况下,最好使用条件变量在需要唤醒并执行所有必需操作时通知第二个线程.