升压shared_lock。阅读preferred? [英] Boost shared_lock. Read preferred?

查看:113
本文介绍了升压shared_lock。阅读preferred?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我被检查出一个读/写锁Boost库(版本1.45)。当我跑就可以了我的测试中,这似乎是shared_ptr的是preferring我读线程,也就是当我的作家试图把锁它的操作,并没有停止任何后续发生的读取。

I was checking out the boost library(version 1.45) for a reader/writer lock. When I ran my tests on it, it seemed like the shared_ptr was preferring my reader threads, i.e. when my writer tried to take the lock for its operation, it didn't stop any subsequent reads from occurring.

是否有可能在推动改变这种行为?

Is it possible in boost to change this behavior?

using namespace std;
using namespace boost;

mutex outLock;
shared_mutex workerAccess;
bool shouldIWork = true;

class WorkerKiller
{
public:   

    void operator()()  
    {
        upgrade_lock<shared_mutex> lock(workerAccess); 
        upgrade_to_unique_lock<shared_mutex> uniqueLock(lock);

        cout << "Grabbed exclusive lock, killing system" << endl;
        sleep(2);
        shouldIWork = false;
        cout << "KILLING ALL WORK" << endl;  
    }  

private:  
};

class Worker
{  
public:   

    Worker()
    {  
    }  

    void operator()()  
    {
        shared_lock<shared_mutex> lock(workerAccess); 

        if (!shouldIWork) {
            outLock.lock();
            cout << "Workers are on strike.  This worker refuses to work" << endl;
            outLock.unlock();
        } else {
            sleep(1);

            outLock.lock(); 
            cout << "Worked finished her work" << endl;
            outLock.unlock(); 
        }
    }  
};  

int main(int argc, char* argv[])  
{  
    Worker w1;
    Worker w2;
    Worker w3;
    Worker w4;
    WorkerKiller wk;

    boost::thread workerThread1(w1);
    boost::thread workerThread2(w2);

    boost::thread workerKillerThread(wk);

    boost::thread workerThread3(w3);
    boost::thread workerThread4(w4);

    workerThread1.join();
    workerThread2.join();
    workerKillerThread.join();
    workerThread3.join();

    return 0;
}

这里是输出每次:

任职完成了她的工作结果
工作完成了她的工作结果
工作完成了她的工作结果
工作完成了她的工作结果
抓住独占锁,造成系统结果
杀害所有工作结果

Worked finished her work
Worked finished her work
Worked finished her work
Worked finished her work
Grabbed exclusive lock, killing system
KILLING ALL WORK

我的要求

如果作家想抓独占锁,我想对所有previous读操作完成。然后所有后续读操作来阻止。

If the writer tried to grab an exclusive lock, I'd like for all previous read operations to finish. And then all subsequent read operations to block.

推荐答案

我有点晚了这个问题,但我相信我有一些相关的信息。

I'm a little late to this question, but I believe I have some pertinent information.

shared_mutex 的提案,C ++委员会,升压库的基础上,故意没有指定一个API,让读者也作家的优先级。这是因为亚历山大捷列霍夫前提出大约十年的算法是完全公平的。它可以让操作系统决定下一个线程获得互斥是否是读者或作家,操作系统是为下一个线程是否是一个读取器或写入完全无知的。

The proposals of shared_mutex to the C++ committee, which the boost libs are based on, purposefully did not specify an API to give readers nor writers priority. This is because Alexander Terekhov proposed an algorithm about a decade ago that is completely fair. It lets the operating system decide whether the next thread to get the mutex is a reader or writer, and the operating system is completely ignorant as to whether the next thread is a reader or writer.

由于该算法中,需要用于指定是否一个阅读器或写入器是preferred消失。以我所知,升压库现在(1.52提高)这公平算法来实现。

Because of this algorithm, the need for specifying whether a reader or writer is preferred disappears. To the best of my knowledge, the boost libs are now (boost 1.52) implemented with this fair algorithm.

的捷列霍夫算法由具有读/写互斥由两个门的:GATE1和GATE2。在一个时间只有一个线程能够通过每个门。门可以用一个互斥体和两个条件变量来实现。

The Terekhov algorithm consists of having the read/write mutex consist of two gates: gate1 and gate2. Only one thread at a time can pass through each gate. The gates can be implemented with a mutex and two condition variables.

读者和作家试图通过GATE1。为了通过GATE1一个作家线程不是目前GATE1内它必须是真实的。如果有,则线程试图穿过GATE1块

Both readers and writers attempt to pass through gate1. In order to pass through gate1 it must be true that a writer thread is not currently inside of gate1. If there is, the thread attempting to pass through gate1 blocks.

一旦读线程通过GATE1已经阅读互斥体的所有权。

Once a reader thread passes through gate1 it has read ownership of the mutex.

当一个作家线穿过GATE1还必须获得互斥写所有权之前通过GATE2。它不能通过GATE2传递直到内部的GATE1降到零读者数量

When a writer thread passes through gate1 it must also pass through gate2 before obtaining write ownership of the mutex. It can not pass through gate2 until the number of readers inside of gate1 drops to zero.

这是一个公平的算法,因为当有GATE1内只有0或更多的读者,它是由操作系统作为下一个线程是否GATE1内部得到的是一个读者或作家。一个作家成为优先已通过GATE1通过后才能,因此是排在后面,以获得互斥体的所有权。

This is a fair algorithm because when there are only 0 or more readers inside of gate1, it is up to the OS as to whether the next thread to get inside of gate1 is a reader or writer. A writer becomes "prioritized" only after it has passed through gate1, and is thus next in line to obtain ownership of the mutex.

我用你的例子对一个例子实施最终成为 shared_timed_mutex 在C ++ 14(稍作修改,以你的例子)编译。下面的code称之为 shared_mutex 这是有人提议,当它有它的名字。

I used your example compiled against an example implementation of what eventually became shared_timed_mutex in C++14 (with minor modifications to your example). The code below calls it shared_mutex which is the name it had when it was proposed.

我得到了以下输出(都具有相同的可执行文件):

I got the following outputs (all with the same executable):

有时:

Worked finished her work
Worked finished her work
Grabbed exclusive lock, killing system
KILLING ALL WORK
Workers are on strike.  This worker refuses to work
Workers are on strike.  This worker refuses to work

有时:

Worked finished her work
Grabbed exclusive lock, killing system
KILLING ALL WORK
Workers are on strike.  This worker refuses to work
Workers are on strike.  This worker refuses to work
Workers are on strike.  This worker refuses to work

有时:

Worked finished her work
Worked finished her work
Worked finished her work
Worked finished her work
Grabbed exclusive lock, killing system
KILLING ALL WORK

我相信这应该是理论上的可能也获得其他的输出,虽然我没有确认实验。

I believe it should be theoretically possible to also obtain other outputs, though I did not confirm that experimentally.

在充分披露的利益,这里是确切的code我执行:

In the interest of full disclosure, here is the exact code I executed:

#include "../mutexes/shared_mutex"
#include <thread>
#include <chrono>
#include <iostream>

using namespace std;
using namespace ting;

mutex outLock;
shared_mutex workerAccess;
bool shouldIWork = true;

class WorkerKiller
{
public:   

    void operator()()  
    {
        unique_lock<shared_mutex> lock(workerAccess); 

        cout << "Grabbed exclusive lock, killing system" << endl;
        this_thread::sleep_for(chrono::seconds(2));
        shouldIWork = false;
        cout << "KILLING ALL WORK" << endl;  
    }  

private:  
};

class Worker
{  
public:   

    Worker()
    {  
    }  

    void operator()()  
    {
        shared_lock<shared_mutex> lock(workerAccess); 

        if (!shouldIWork) {
            lock_guard<mutex> _(outLock);
            cout << "Workers are on strike.  This worker refuses to work" << endl;
        } else {
            this_thread::sleep_for(chrono::seconds(1));

            lock_guard<mutex> _(outLock);
            cout << "Worked finished her work" << endl;
        }
    }  
};  

int main()  
{  
    Worker w1;
    Worker w2;
    Worker w3;
    Worker w4;
    WorkerKiller wk;

    thread workerThread1(w1);
    thread workerThread2(w2);

    thread workerKillerThread(wk);

    thread workerThread3(w3);
    thread workerThread4(w4);

    workerThread1.join();
    workerThread2.join();
    workerKillerThread.join();
    workerThread3.join();
    workerThread4.join();

    return 0;
}

这篇关于升压shared_lock。阅读preferred?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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