问题描述
在多线程Linux应用程序上,我在关键部分使用了互斥锁.除公平性问题外,这非常有效.可能发生的情况是,某个线程离开关键部分并立即重新进入并没有给其他线程带来任何机会.例如
On a multi-threaded Linux application I use a mutex for critical sections. This works very well except for the fairness issue. It can happen that a thread leaving a critical section and re-entering right away does not give any other thread a chance. For example
while(true)
{
critsect.enter();
... do calculations ...
... maybe call a blocking operation so we sleep ...
critsect.leave();
}
很可能会阻止其他任何线程进入相同的关键部分.互斥体不公平.
might very likely stop any other thread to enter the same critical section. Mutexe are not fair.
是否存在解决公平关键部分的解决方案?我当时正在考虑添加一个队列,以便按照到达"的顺序执行关键部分.或者,如果其他线程正在等待,则至少要有一个计数器在解锁后执行pthread_yield().
Is there a solution to making a fair critical section? I was thinking of adding a queue so that critical sections are executed in the order of their 'arrival'. Alternatively at least a counter to maybe do a pthread_yield() after unlock if other threads are waiting.
对于这种要求有推荐的做法吗?
Is there a recommended practice for this kind of requirement?
推荐答案
您可以按照以下步骤在pthread互斥对象的顶部构建FIFO票证锁定":
You can build a FIFO "ticket lock" on top of pthreads mutexes, along these lines:
#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);
}
在这种方案下,当线程处于受票锁保护的关键部分内时,不保留任何低级pthread互斥体,从而允许其他线程加入队列.
Under this kind of scheme, no low-level pthreads mutex is held while a thread is within the ticketlock protected critical section, allowing other threads to join the queue.
这篇关于一般关键部分(Linux)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!