Linux中是否有等待队列为FIFO的锁?这似乎是一个很明显的问题,但我刚刚发现pthread互斥锁不是FIFO,信号量似乎也不是FIFO(我正在2.4内核上工作(作业))...
Linux是否有带有FIFO等待队列的锁,或者有没有使用现有机制轻松实现它的方法?
Linux中是否有等待队列为FIFO的锁?这似乎是一个很明显的问题,但我刚刚发现pthread互斥锁不是FIFO,信号量似乎也不是FIFO(我正在2.4内核上工作(作业))...
Linux是否有带有FIFO等待队列的锁,或者有没有使用现有机制轻松实现它的方法?
这是一种使用pthread原语构建简单队列式“票据锁”的方法。它应该可以给你一些想法:
#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);
}
如果您需要100%正确的FIFO排序,请选择caf的pthread ticket lock。
如果您对99%感到满意并且更喜欢简单性,则信号量或互斥锁实际上可以很好地完成。
票据锁可以跨进程使用:
您需要使用共享内存、进程共享互斥锁和条件变量,在互斥锁被锁定时处理进程死亡(->鲁棒互斥锁)...这有点过度,所有我需要的是不同的实例不同时调度并且顺序大致公平。
使用信号量:
static sem_t *sem = NULL;
void fifo_init()
{
sem = sem_open("/server_fifo", O_CREAT, 0600, 1);
if (sem == SEM_FAILED) fail("sem_open");
}
void fifo_lock()
{
int r;
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) fail("clock_gettime");
ts.tv_sec += 5; /* 5s timeout */
while ((r = sem_timedwait(sem, &ts)) == -1 && errno == EINTR)
continue; /* Restart if interrupted */
if (r == 0) return;
if (errno == ETIMEDOUT) fprintf(stderr, "timeout ...\n");
else fail("sem_timedwait");
}
void fifo_unlock()
{
/* If we somehow end up with more than one token, don't increment the semaphore... */
int val;
if (sem_getvalue(sem, &val) == 0 && val <= 0)
if (sem_post(sem)) fail("sem_post");
usleep(1); /* Yield to other processes */
}
订单几乎100%先进先出。
注意:这是在4.4 Linux内核下,2.4可能会有所不同。