【问题标题】:Ownership of mutex is not transferred to another thread互斥锁的所有权不会转移到另一个线程
【发布时间】:2016-05-09 16:40:04
【问题描述】:
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
#include <csignal>

namespace
{
    volatile std::sig_atomic_t gSignalStatus = 1;
}

void sig_handler(int sig){
    gSignalStatus = 0;
}

boost::shared_mutex g_mutex;

using namespace std;

void reader(int id)
{
    cerr<<"reader"<<id<<"started"<<endl;
    while(gSignalStatus) {
        boost::shared_lock<boost::shared_mutex> lock(g_mutex);
        cerr << "reader"<<id << ": Got the lock" << endl;
        boost::this_thread::sleep(boost::posix_time::milliseconds(200));
    }
}

void writer(int id)
{
    cerr<<"writer"<<id<<"started"<<endl;
    while(gSignalStatus) {
        boost::upgrade_lock<boost::shared_mutex> lock(g_mutex);
        boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock);
        cout <<"writer"<< id << ": Got the lock" << endl;
        boost::this_thread::sleep(boost::posix_time::milliseconds(200));
    }
}

int main(int argc, char* argv[])
{
    std::signal(SIGINT, sig_handler);

    std::vector<boost::thread*> writerthread(1);
    std::vector<boost::thread*> readerthread(4);
    int id = 0;
    for(auto& w:writerthread) w = new boost::thread(writer, id++);

    id=0;
    for(auto& r:readerthread) r = new boost::thread(reader, id++);

    for(auto& w:writerthread){
        w->join();
        delete w;
    }
    for(auto&r:readerthread){
        r->join();
        delete r;
    }

    return 0;
}

我实现了多读/单写示例。

问题是一旦 writer 拥有 mutex 或 reader(s) 拥有 mutex,所有权不会转移到其相反的线程(readers->writer / writer->读者)

所以程序的输出可以是两个之一。

当作家获得锁时

writer0started
readerwriterreader0: Got the lock
readerreader21started30started
started

started
writer0: Got the lock
writer0: Got the lock
writer0: Got the lock
writer0: Got the lock
writer0: Got the lock

当读者获得锁时

writerreader0started
reader3startedreader
0: Got the lock
0reader2reader3: Got the lock
reader1started
reader1: Got the lock
started
started
reader2: Got the lock
reader0: Got the lock
reader3: Got the lock
reader1: Got the lock
reader2: Got the lock
reader1: Got the lock
reader2: Got the lock
reader0: Got the lock
reader3: Got the lock
readerreader3: Got the lock
reader2: Got the lock
0: Got the lock

输出与我预期的不同。

我所期望的是作者和读者交替拥有锁。

这种行为正常吗?

是否有任何锁定机制的偏好?即shared_lockupgrade_lock 更受欢迎。

【问题讨论】:

  • "问题是一旦 writer 拥有 mutex 或 reader(s) 拥有 mutex,所有权不会转移到它的对立线程(readers->writer / writer->readers)" i> 互斥体(mutually exclusive)同步机制的全部目的不就是这样吗?你的意思是实现read/write lock
  • 我认为这已经可以从当前的 c+ 标准 BTW 中获得。不一定要使用 boost。

标签: c++ multithreading boost mutex


【解决方案1】:

问题在于,一旦另一个人抓住了互斥锁,读者或作者都无法轻松克服这些紧密的循环。看看你的循环要点:

  1. 锁定互斥体
  2. 睡觉
  3. 释放互斥锁
  4. 转到步骤 1

第 3 步之后的窗口是读取器或写入器获取互斥锁的唯一机会。这个窗口很短,所以它实际上抓住它的机会很小。这就是为什么您只能看到写入者或读取者打印到控制台的原因。实际上,如果您永远等待,您很可能会看到不同的实体将有机会发挥作用。

那么如何解决呢?这很简单:只需将睡眠移出锁,就像这样:

void writer(int id)
{
    cerr << "writer" << id << "started" << endl;
    while(gSignalStatus) {
        {
            boost::upgrade_lock<boost::shared_mutex> lock(g_mutex);
            boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock);
            cout << "writer" << id << ": Got the lock" << endl;
        }
        boost::this_thread::sleep(boost::posix_time::milliseconds(200));
    }
}

void reader(int id)
{
    cerr << "reader" << id << "started" << endl;
    while(gSignalStatus) {
        {
            boost::shared_lock<boost::shared_mutex> lock(g_mutex);
            cerr << "reader" << id << ": Got the lock" << endl;
        }
        boost::this_thread::sleep(boost::posix_time::milliseconds(200));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 2023-03-21
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2012-12-14
    相关资源
    最近更新 更多