首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >基于futex的4字节单写/多读锁

基于futex的4字节单写/多读锁
EN

Stack Overflow用户
提问于 2010-10-19 01:36:55
回答 1查看 650关注 0票数 2

寻找单写器/多读取器锁的最小futex-based实现,除了单个4字节的futex状态变量外,不需要任何空间开销。

一些背景知识:我有一个应用程序,它将在数千万到数亿个小对象中嵌入一个锁。由于锁的细粒度特性和应用程序的结构,我期望最小的争用。此外,作家将是稀有的,而有竞争力的作家更是罕见。由于所有这些原因,在这个特定的环境中,(在理论上)容易出现“雷鸣般的”现象的解决方案是相当可以接受的。

EN

回答 1

Stack Overflow用户

发布于 2016-07-24 23:33:08

您可以在https://gist.github.com/smokku/653c469d695d60be4fe8170630ba8205上找到我的实现

这个想法是,可以只有一个线程获取写锁(futex值0),锁可以是打开的(futex值1),或者可以有许多读取线程(futex值大于1)。因此,低于1 (只有一个)的值会阻塞futex上的读取器和写入器,而高于1的值只会阻塞写入器。解锁线程会唤醒其中一个等待线程,但您需要小心,不要消耗仅由写线程唤醒的读取器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define cpu_relax() __builtin_ia32_pause()
#define cmpxchg(P, O, N) __sync_val_compare_and_swap((P), (O), (N))

static unsigned _lock = 1; // read-write lock futex
const static unsigned _lock_open = 1;
const static unsigned _lock_wlocked = 0;

static void _unlock()
{
    unsigned current, wanted;
    do {
        current = _lock;
        if (current == _lock_open) return;
        if (current == _lock_wlocked) {
            wanted = _lock_open;
        } else {
            wanted = current - 1;
        }
    } while (cmpxchg(&_lock, current, wanted) != current);
    syscall(SYS_futex, &_lock, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0);
}

static void _rlock()
{
    unsigned current;
    while ((current = _lock) == _lock_wlocked || cmpxchg(&_lock, current, current + 1) != current) {
        while (syscall(SYS_futex, &_lock, FUTEX_WAIT_PRIVATE, current, NULL, NULL, 0) != 0) {
            cpu_relax();
            if (_lock >= _lock_open) break;
        }
        // will be able to acquire rlock no matter what unlock woke us
    }
}

static void _wlock()
{
    unsigned current;
    while ((current = cmpxchg(&_lock, _lock_open, _lock_wlocked)) != _lock_open) {
        while (syscall(SYS_futex, &_lock, FUTEX_WAIT_PRIVATE, current, NULL, NULL, 0) != 0) {
            cpu_relax();
            if (_lock == _lock_open) break;
        }
        if (_lock != _lock_open) {
            // in rlock - won't be able to acquire lock - wake someone else
            syscall(SYS_futex, &_lock, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0);
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3964776

复制
相关文章

相似问题

处理多读和单写

11

读锁写锁

34

读/写锁

104

多读和单写线程安全?

12

文件读/写锁

40
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文