C++ 根据C++;11(语言/图书馆)标准?
TL;DR:当同时调用两个可能不同的函数时发生数据竞争,那么说特定函数是“线程安全”是什么意思?当人们告诉“const意味着/暗示着C++11中的线程安全”时,这个问题尤其重要C++ 根据C++;11(语言/图书馆)标准?,c++,multithreading,c++11,thread-safety,C++,Multithreading,C++11,Thread Safety,TL;DR:当同时调用两个可能不同的函数时发生数据竞争,那么说特定函数是“线程安全”是什么意思?当人们告诉“const意味着/暗示着C++11中的线程安全”时,这个问题尤其重要 考虑以下示例: class X { int x, y; // are some more complex type (not supported by `std::atomic`) std::mutex m; public: void set_x (int new_x) {x = new_x;}
考虑以下示例:
class X {
int x, y; // are some more complex type (not supported by `std::atomic`)
std::mutex m;
public:
void set_x (int new_x) {x = new_x;} // no mutex
void get_x () const {return x;}
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;}
}
X类{
int x,y;//是更复杂的类型(std::atomic不支持)
std::互斥m;
公众:
void set_x(int new_x){x=new_x;}//无互斥
void get_x()常量{return x;}
无效集(整型新集){
std::lock_guard guard(m);//带互斥的保护设置器
y=新的y;
}
void get_y()常量{return y;}
}
是否设置线程安全
当然,set_x
不是线程安全的,因为从两个线程同时调用它会导致数据竞争
是线程安全的get\u x
、get\u y
和set\u y
吗?
存在两种可能的理由:
get\u x
/get\u y
/set\u y
不会导致数据竞争get\u x
(或get\u y
)和set\u x
(或set\u y
)会导致数据争用问题摘要 哪种推理是正确的
set_x
/get_x
,但对于set_y
/get_y
无效,因为这将导致得出结论set_y
和get_y
是线程安全的,但是类Y
不是因为从两个线程同时调用set\u Y
和get\u Y
会导致数据竞争相关线程 请注意,我已经阅读了以下相关线程:
- 这是你的责任
set__y
是线程安全的
注意,线程安全不是由C++标准明确定义的,它使用术语“数据竞争”。有关更多信息,请参阅Nicol Bolas的答案:线程安全并不总是黑白相间的
const函数意味着线程安全的按位const或内部同步 “const函数意味着线程安全”一词在上下文中被滥用 “const函数意味着线程安全”的意思是,从多个线程调用const函数应该是安全的(,而不在另一个线程中同时调用非const函数)AS(29∶43)声明了自己,在这个上下文中,线程安全的方法是位-位const <强>或内部同步,如果同时调用其他非const函数,则这不是真正的线程安全。
< P> C++标准不使用“线程安全”这样的术语;它使用更具体的语言。人类使用“线程安全”这样的术语是因为我们发现它们很有用 线程安全函数的一般概念是,在调用时,假设没有其他人出错,则不会创建数据竞争get_x
是线程安全的;在所有条件相同的情况下,您可以从任意数量的线程调用它,并得到合理的结果。即使不能与set_x
同时调用它,这也是正确的,因为这会导致数据争用。但是数据竞争的原因是您调用了一个非线程安全函数:set\u x
将函数分类为“线程安全”或“非线程安全”的关键在于指定责任。如果只调用“线程安全”函数,则代码是“线程安全”的。如果您偏离了“线程安全”函数的边界,那么正是您偏离了这些边界导致了数据竞争
并发的set\ux
调用导致数据竞争不是get\ux
的错误
至于get/set_y
的问题,如前所述,“线程安全”不是一个计算术语或严格的标准术语。这是一个人类术语,是计算现实的简化
“线程安全”的规则基本上是,“您可以同时调用任何线程安全函数和任何其他线程安全函数”。如果不能同时调用get_y
和set_y
,则它们不是“线程安全的”
从严格的角度来看,描述这两个函数的准确方法是set_y
与对同一对象的set_y
的其他调用同步,而get_y
与对同一对象的get_y
的其他调用同步。事实上我们没有