我有一些线程要写资源,一些线程要读资源,但是pthread_rwlock会导致很多上下文切换。所以我想办法避免它。但我不确定它是否安全。
这是代码:

sig_atomic_t slot = 0;

struct resource {
    sig_atomic_t in_use;  /*Counter,if in_use, not zero*/
    .....
} xxx[2];

int read_thread()
{
    i = slot; /*avoid slot changes in process */
    xxx[i].in_use++;
    read(xxx[i]);
    xxx[i].in_use--;
}

int write_thread()
{
    mutex_lock;  /*mutex between write threads */

    if (slot == 0) {
    while(xxx[1].in_use != 0);  /*wait last read thread in slot 1*/
    clear(xxx[1]);
    write(xxx[1]);
    slot = 1;
    } else if (slot == 1) {
    while(xxx[0].in_use != 0);
    clear(xxx[0]);
    write(xxx[0]);
    slot = 0;
    }

    mutex_unlock;
}

这样行吗?成本是存储量的2倍和3个原子变量。
谢谢!

最佳答案

你的策略是让写作者在不同的时段写作,而不是让读者从不同的时段阅读。在写入完成后,您将切换读取槽号。但是,你会有一场比赛。

slot    reader             writer1            writer2
----    ------             -------            -------
0                          mutex_lock
        i = 0
                           ... slot=1
1                          mutex_unlock       mutex_lock
                                              ... clear(xxx[0])
        xxx[0].in_use++
        read(xxx[0])                          write(xxx[0])

不过,总的来说,这种策略可能导致作家挨饿(这是一个作家可能永远旋转)。
但是,如果您愿意容忍这种情况,那么让xxx[]成为resource的两个指针数组会更安全。让读者始终从xxx[0]中阅读,让作者争用xxx[1]上的更新。当writer完成更新xxx[1]时,它在xxx[0]xxx[1]上使用cas。
struct resource {
    sig_atomic_t in_use;  /*Counter,if in_use, not zero*/
    sig_atomic_t writer;
    .....
} *xxx[2];

void read_thread()
{
    resource *p = xxx[0];
    p->in_use++;
    while (p->writer) {
        p->in_use--;
        p = xxx[0];
        p->in_use++;
    }
    read(*p);
    p->in_use--;
}

void write_thread()
{
    resource *p;
    mutex_lock;  /*mutex between write threads */
    xxx[1]->writer = 1;

    while(xxx[1]->in_use != 0);  /*wait last read thread in slot 1*/
    clear(xxx[1]);
    write(xxx[1]);
    xxx[1] = CAS(&xxx[0], p = xxx[0], xxx[1]);
    assert(p == xxx[1]);

    xxx[0]->writer = 0;
    mutex_unlock;
}

如果您希望避免写入程序不足,但希望获得spinlocks的性能,那么可以考虑使用spinlocks而不是mutex锁来实现自己的读写器锁。在google上搜索“read-write spinlock implementation”指向this page,我发现这是一个有趣的阅读。

关于c - 原子变量可以代替pthread_rwlock吗?它可以无锁吗,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11237036/

10-15 00:49