问题描述
我有两个线程,一个工作在一个紧的循环,另一个偶尔需要执行与第一个同步:
I have a two threads, one which works in a tight loop, and the other which occasionally needs to perform a synchronization with the first:
// 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不等待锁定,重新锁定并返回工作。
My intention is that thread 2 can, by taking the lock, effectively pause thread 1 and perform the necessary synchronization. Thread 1 can also offer to pause, by unlocking, and if thread 2 is not waiting on lock, re-lock and return to work.
我遇到的问题是互斥体不公平,所以线程1快速重新锁定互斥和饥饿线程2.我试图使用 pthread_yield
,到目前为止它似乎运行好,但我不确定它将适用于所有系统/核心数。有没有办法保证线程1将总是输出到线程2,即使在多核系统上?
The problem I have encountered is that mutexes are not fair, so thread 1 quickly re-locks the mutex and starves thread 2. I have attempted to use pthread_yield
, and so far it seems to run okay, but I am not sure it will work for all systems / number of cores. Is there a way to guarantee that thread 1 will always yield to thread 2, even on multi-core systems?
什么是最有效的方式来处理这个同步过程?
What is the most effective way of handling this synchronization process?
推荐答案
您可以在pthreads互斥体顶部构建一个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);
}
在这种方案下,没有低级pthreads互斥线程在ticketlock保护的关键部分内,允许其他线程加入队列。
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.
这篇关于pthreads:由快速重锁导致的线程饥饿的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!