linux - 公平临界区 (Linux)

标签 linux pthreads mutex critical-section

在多线程 Linux 应用程序中,我对关键部分使用互斥锁。除了公平性问题外,这非常有效。一个线程离开临界区并立即重新进入可能不会给任何其他线程机会。例如

while(true)
{
    critsect.enter();
    ... do calculations ...
    ... maybe call a blocking operation so we sleep ...
    critsect.leave();
}

很可能会阻止任何其他线程进入同一临界区。互斥锁不公平。

是否有解决方案来制作公平的临界区?我正在考虑添加一个队列,以便关键部分按照它们“到达”的顺序执行。或者,如果其他线程正在等待,至少有一个计数器可以在解锁后执行 pthread_yield()。

是否有针对此类要求的推荐做法?

最佳答案

您可以在 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 互斥量,从而允许其他线程加入队列。

关于linux - 公平临界区 (Linux),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6449732/

相关文章:

linux - 从 bash 启动进程而不继承文件描述符

linux - nanomsg 中是否可以进行 IP 多播?

c++ - 无法将 ‘std::function<void*()>’ 转换为 ‘void* (*)(void*)’

c++ - Pthreads:为 pthread_cond_wait 使用 While 循环背后的逻辑

c - 如何知道哪个线程正在执行一个函数?

当同一个客户端同时多次请求同一个脚本时的 PHP session 处理

c++ - 互斥量超出范围时会解锁吗?

python - 无法安装 SRC - Linux

java - Quartz 作业正在运行 - 无法连接到 SFTP 服务器 - 连接重置

c# - 使用命名互斥体