我有两个线程,一个在紧密循环中工作,另一个偶尔需要与第一个线程执行同步:
// 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);
}
我的意图是线程 2 可以通过获取锁来有效地暂停线程 1 并执行必要的同步。线程 1 还可以通过解锁来暂停,如果线程 2 没有等待锁定,则重新锁定并返回工作。
我遇到的问题是互斥体不公平,因此线程1快速重新锁定互斥体并饿死线程2。我尝试使用pthread_yield
,到目前为止它似乎运行良好,但我不确定它是否适用于所有系统/核心数量。有没有办法保证线程 1 始终让位于线程 2,即使在多核系统上也是如此?
处理此同步过程的最有效方法是什么?
您可以在 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);
}
在这种方案下,当线程位于票证锁保护的关键部分内时,不会保留低级 pthreads 互斥体,从而允许其他线程加入队列。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)