根据C ++ 11(语言/库)标准,线程安全(类成员)函数的定义是什么? [英] What is the definition of a thread safe (class member) function according to the C++11 (Language/Library) Standard?

查看:68
本文介绍了根据C ++ 11(语言/库)标准,线程安全(类成员)函数的定义是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当通过同时调用两个可能不同的函数发生数据争用时,说特定于 的函数是线程安全的"是什么意思?在人们说" const意味着/暗示C ++ 11中的线程安全"时,这个问题尤其重要. [1]

What is meant by saying a specific function is 'thread-safe' as a data race occurs by simultaneously calling two possibly different functions? This question is especially relevant in the context of people telling "const means/implies thread-safe in C++11" [1][2]

请考虑以下示例:

请考虑以下基本类:

class X {
    int x; // are some more complex type (not supported by `std::atomic`)
public:
    void set_x (int new_x) {x = new_x;}
    void get_x () const {return x;}
}

set_x 线程安全吗?

当然, set_x 不是线程安全的,因为从两个线程同时调用它会导致数据争用.

Is set_x thread safe?

Off course, set_x is not thread safe as calling it from two threads simultaneously results in a data race.

存在两个可能的理由:

  1. 是的,它是线程安全的,因为从两个线程同时调用 get_x 不会导致数据争用.
  2. 不,它不是线程安全的,因为从两个线程同时调用 get_x set_x 会导致数据争用.
  1. Yes, it is thread safe, as calling get_x from two threads simultaneously does not result in a data race.
  2. No, it is not thread safe, as calling get_x and set_x from two threads simultaneously results in a data race.

哪个是正确的推理?

请考虑以下相关类:

class Y {
    int y;
    std::mutex m; // mutex added
public:
    void set_y (int new_y) {
        std::lock_guard<std::mutex> guard(m); // guard setter with mutex
        y = new_y;
    }
    void get_y () const {return y;}
}

set_y 线程安全吗?

存在两个可能的理由:

Is set_y thread safe?

Two possible reasonings exists:

  1. 是的,它是线程安全的,因为从两个线程同时调用 set_y 不会导致数据争用.
  2. 不,它不是线程安全的,因为从两个线程同时调用 set_y get_y 会导致数据争用.
  1. Yes, it is thread safe, as calling set_y from two threads simultaneously does not result in a data race.
  2. No, it is not thread safe, as calling set_y and get_y from two threads simultaneously results in a data race.

哪个是正确的推理?

未更改:与 get_x 相同的选项.

Nothing changed: same options as for get_x.

当然,正确的线程安全实现是:

Off course the correct thread safe implementation is:

class Z {
    int z;
    mutable std::mutex m; // could be replaced by std::shared_mutex in C++17 (or std::shared_timed_mutex in C++14);
public:
    void set_z (int new_z) {
        std::lock_guard<std::mutex> guard(m);
        z = new_z;
    }
    void get_z () const {
        std::lock_guard<std::mutex> guard(m); // guard getter with mutex
        return z;
    }
}

当然,对于基本类型为 int 的人,可以通过使用 std :: atomic< int> <来避免使用 std :: mutex /code>作为 z ;

Off course, for a basic type as int, one may avoid the need for std::mutex by using std::atomic<int> as member type for z;

哪种推理是正确的?

  1. 一个函数是线程安全的,如果同时从两个线程调用该函数不会导致数据争用.可以在示例1中工作,但在示例2中失败,因为这将得出以下结论: set_y get_y 是线程安全的,但类为 Y 不是因为从两个线程同时调用 set_y get_y 会导致数据争用.
  2. 一个函数是线程安全的,前提是它不访问任何未经另一个函数进行内部同步就可以修改的内存.在我看来,这是最一致的选择,但不是通常使用的方式(请参阅相关主题).
  1. A function is thread safe iff calling it from two threads simultaneously does not result in a data race. Could work for example 1, but fails in example 2, as this would result to the conclusion that set_y and get_y are thread safe, but class Y isn't as calling set_y and get_y from two threads simultaneously results in a data race.
  2. A function is thread safe iff it does not access any memory that could be modified without internal synchronization by another function. This seems to me the most consistent option, but is not the way it is often used (see related threads).

相关线程

请注意,我已阅读以下相关主题:

Related threads

Note that I have read the following related threads:

推荐答案

我还将遵循以下语句:

2.如果某个函数不访问任何未经另一个函数进行内部同步就可以修改的内存,则该函数是线程安全的.在我看来,这是最一致的选择,但不是经常使用的方式.

只要正确使用共享变量原子和互斥锁来实现同步,我就不会发现您的上述声明有任何问题.

As long as the shared variable is atomic and mutex are properly used to achieve synchronization, i don,t see any problem with your above statement.

这篇关于根据C ++ 11(语言/库)标准,线程安全(类成员)函数的定义是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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