C ++ - 最快的多功能读卡器/单编剧保护共享资源 [英] Fastest Multi-Reader / Single Writer Protection for Shared Resources - C++

查看:160
本文介绍了C ++ - 最快的多功能读卡器/单编剧保护共享资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想确认我的做法是极其的快速并适当的大多是多个读取的共享资源的跨平台保护,使用C ++单作家的做法。它有利于作家,这样当他们进入所有当前线程被允许完成,但是任何类型的所有新线程必须等待。这两个函数的反应该是显而易见的。

我已经做了阅读提示,提升 shared_mutex 和其他类型rwlocks不落实得很好,应该尽量避免。事实上,shared_mutex不会使它成为的C ++ 0x 我要了。请参见这种反应由安东尼·威廉姆斯的。

现在看来,这甚至有可能写入到一个整数,如果它是正确对齐不需要任何形式的锁定。有这么多的文章在那里,对这个问题有什么好的读书,所以我不必从芜存菁排序?

 无效AquireReadLock(无效)
{
    互斥::进入();
    如果(READ_STATE ==真)
    {
        iReaders ++;
        互斥::离开();
        返回;
    }
    其他
    {
        互斥::离开();
        睡眠(1);
        AquireReadLock();
        返回;
    }
}无效AquireWriteLock(无效)
{
    互斥::进入();
    READ_STATE = FALSE;
    如果(iReaders!= 0)
    {
        互斥::离开();
        睡眠(1);
        AquireWriteLock();
        返回;
    }
    其他
    {
        互斥::离开();
        返回;
    }
}


解决方案

离开shared_mutex的决定是独立做出任何质量问题。这一决定是科纳妥协在2007年这一妥协秋季提出的一部分,旨在减少的C ++ 0x功能集,从而在2009年出货标准它没有工作,但尽管如此,这是什么道理。

shared_mutex的意志为委员会完成的C ++ 0x后列入一份技术报告(即TR2)进行讨论。在图书馆工作组主席已经联系过我关于这个主题。那是不是说shared_mutex将在TR2。只是,这将被讨论。

您实现AquireReadLock和AquireWriteLock已经在他们每秒处于争时吃的速度堆栈帧一次的缺点。并且当争用结束后,它们延缓至第二反应之前。这使得他们既堆栈饥饿和贫困表演(对不起)。

如果你有兴趣,有shared_mutex的完整描述和实现在这里:

<一个href=\"http://home.roadrunner.com/~hinnant/mutexes/locking.html\">http://home.roadrunner.com/~hinnant/mutexes/locking.html

在code不是提升的一部分,但不进行升压开源许可。随意使用它,只是不停的版权与源$ C ​​$ C。没有其他附加条件。下面是它的模拟您AquireReadLock:

 无效
shared_mutex :: lock_shared()
{
    的std :: unique_lock&LT;&为mutex_t GT; LK(mut_);
    而((STATE_&安培; write_entered_)||(STATE_&安培; n_readers_)== n_readers_)
        gate1_.wait(LK);
    count_t num_readers =(STATE_&放大器; n_readers_)+ 1;
    STATE_&安培; =〜n_readers_;
    STATE_ | = num_readers;
}

这里是它的模拟您AquireWriteLock:

 无效
shared_mutex ::锁()
{
    的std :: unique_lock&LT;&为mutex_t GT; LK(mut_);
    而(STATE_&安培; write_entered_)
        gate1_.wait(LK);
    STATE_ | = write_entered_;
    而(STATE_&安培; n_readers_)
        gate2_.wait(LK);
}

我认为这对C一个屡试不爽的高性能,公平的读/写互斥执行++。如果您有关于如何改进它的想法,我会欢迎他们。

I would like confirmation that my approach is extremely fast and appropriate for cross platform protection of a shared resource for a mostly multiple reader, single writer approach using C++. It favors writers such that when they enter all current threads are allowed to finish, but all new threads of any type must wait. The reverse of these two functions should be obvious.

The reading I've done suggest that boost shared_mutex and other type rwlocks are not implemented very well and should be avoided. In fact, shared_mutex will not make it into C++0x I take it. See this response by Anthony Williams.

It seems it might even be possible to write to an integer and not need locking of any kind if it is aligned correctly. There is so many articles out there, any good reading on this subject so I don't have to sort the wheat from the chaff?

void AquireReadLock(void)
{
    mutex::enter();
    if(READ_STATE == true)
    {   
        iReaders++;
        mutex::leave();
        return;
    }
    else
    {
        mutex::leave();
        sleep(1);
        AquireReadLock();
        return;
    }   
}

void AquireWriteLock(void)
{
    mutex::enter();
    READ_STATE = false;
    if (iReaders != 0)
    {
        mutex::leave();
        sleep(1);
        AquireWriteLock();
        return;
    }
    else
    {
        mutex::leave();
        return;
    }   
}

解决方案

The decision to leave shared_mutex was made independently of any quality issues. The decision was part of the "Kona compromise" made in the Fall of 2007. This compromise was aimed at reducing the feature set of C++0x so as to ship a standard by 2009. It didn't work, but nevertheless, that is the rationale.

shared_mutex's will be discussed for inclusion to a technical report (i.e. tr2) after the committee has completed C++0x. The chairman on the library working group has already contacted me on this very subject. That is not to say that shared_mutex will be in tr2. Just that it will be discussed.

Your implementation of AquireReadLock and AquireWriteLock have the disadvantage in that they eat a stack frame at the rate of once per second when under contention. And when contention is over, they delay up to a second before reacting. This makes them both stack hungry and poor performing (sorry).

If you are interested, there is a full description and implementation of shared_mutex here:

http://home.roadrunner.com/~hinnant/mutexes/locking.html

The code is not part of boost, but does carry the boost open source license. Feel free to use it, just keep the copyright with the source code. No other strings attached. Here is its analog to your AquireReadLock:

void
shared_mutex::lock_shared()
{
    std::unique_lock<mutex_t> lk(mut_);
    while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
        gate1_.wait(lk);
    count_t num_readers = (state_ & n_readers_) + 1;
    state_ &= ~n_readers_;
    state_ |= num_readers;
}

And here is its analog to your AquireWriteLock:

void
shared_mutex::lock()
{
    std::unique_lock<mutex_t> lk(mut_);
    while (state_ & write_entered_)
        gate1_.wait(lk);
    state_ |= write_entered_;
    while (state_ & n_readers_)
        gate2_.wait(lk);
}

I consider this a well-tested and high-performing, fair read/write mutex implementation for C++. If you have ideas on how to improve it, I would welcome them.

这篇关于C ++ - 最快的多功能读卡器/单编剧保护共享资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆