【问题标题】:C++ Multithread Mutex Lock issueC ++多线程互斥锁问题
【发布时间】:2013-04-16 14:45:56
【问题描述】:

我是 C++ 和多线程的新手。最近在看Lock属性...

假设我有一个里面有互斥锁的类。当我在互斥对象上使用 lock 方法时,如何判断代码的哪一部分被阻塞/锁定?它是阻止/锁定类中的所有成员函数还是仅阻止/锁定我触发锁定的成员函数?

例如(process_data & udf_2)

class data_wrapper
{
private:
    int x;
    some_data data;
    std::mutex m;
public:
    template<typename Function>
    void process_data(Function func)
    {
        std::lock_guard<std::mutex> l(m);
    ......
    }
    void udf_2(int x)
    {
        cout << "Value is " << x; 
    ......
    }
}

==============================

==============================

还有一个问题是,如果我看到一个模板类型T,那么T&amp;T&amp;&amp; 是什么意思?

【问题讨论】:

  • 删除了你的 C# 标签。请仅使用与问题相关的标签。

标签: c++ multithreading templates locking std


【解决方案1】:

互斥锁不会锁定您的对象。互斥锁提供对您程序中位于互斥锁锁定和解锁之间的部分的独占访问。

如果您的程序的一个线程进入process_data() 并正在读取某个变量,同时另一个线程进入udf_2() 并修改相同的变量,您的程序不是线程安全的。换句话说,仅仅在对象内部使用互斥锁并不足以保护它。您必须通过像您的方法process_data() 一样受到保护的方法对变量的访问进行通道化。只有这样你的程序才会是线程安全的。

我希望我说清楚。

【讨论】:

  • 那么是不是意味着类中的所有成员变量都没有被std::lock_guard()锁定?? (例如x,数据)并且它只锁定了process_data()而不是udf_2()?
  • 是的。事实上,没有成员被“锁定”。锁只为进入该方法的线程提供互斥。即只允许一个线程通过。并且由于只允许一个线程通过,因此达到了“锁定”的效果。就好像代码被该线程锁定并且只允许该线程修改某些内容,而其他线程被阻塞并且必须等待锁定线程释放锁定,即离开创建 std::lock_guard 的方法
【解决方案2】:

http://en.cppreference.com/w/cpp/thread/lock_guard

正如您在链接中看到的,一旦程序超出范围(例如 process_data() 方法),std::lock_guard 就会被破坏。

lock_guard 不会锁定所有成员变量,而只是锁定在作用域或 process_data() 中访问的变量

【讨论】:

  • 那么从作用域上来说,是不是只会锁定调用lock_guard()的方法呢?
【解决方案3】:

使用

void process_data(Function func)
{
    std::lock_guard<std::mutex> l(m);
    ......
}

意味着任何到达这一行的线程都不会从锁的构造函数返回,直到任何其他超过锁创建的线程还没有退出作用域。换句话说,您使用省略号表示的代码一次最多只能由一个线程执行,从而有效地序列化了对代码的访问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多