I'm trying to design a thread-safety specification for parts of our existing C++ library. I thought it would be a good idea to look at the guarantees given by the standard library, and stumbled upon §17.6.5.9[res.on.data.races] (from the C++11 standard), which is puzzling me:
- A C ++ standard library function shall not directly or indirectly access objects (1.10) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's arguments, including
this
.- A C ++ standard library function shall not directly or indirectly modify objects (1.10) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's non-const arguments, including
this
.- [ Note: This means, for example, that implementations can't use a static object for internal purposes without synchronization because it could cause a data race even in programs that do not explicitly share objects between threads. — end note ]
(I've included 3. and 4. here because 4. clarifies the preceeding paragraphs in that an object is not considered accessible if I use syncronization to coordinate the accesses. But I am mostly concerned with 2.)
If I apply that to my own library, I cannot have a function like this:
double area_of_circle(double radius)
{
static const double pi = acos(-1.0); // syncronized
return pi*radius*radius; // unsyncronized access to pi
}
The initialization of pi
is syncronized as per §6.7[stmt.dcl]/4, but reading pi
in the return statement could happen concurrently from multiple threads. This cannot introduce a race, since the unsyncronized accesses are only reads, yet paragraph 2. above seems to forbid this.
Note that there is also paragraph 7:
- Implementations may share their own internal objects between threads if the objects are not visible to users and are protected against data races.
This just seems to reiterate 2. and 3. Unless "protected against data races" means something less strict than "not accessible by threads other than the current thread". But I'm not really sure what is actually meant here.
So my questions are:
pi
in the example above?答案 0 :(得分:1)
在这种情况下,我认为“访问”基本上翻译为“使用过的”。
如果你能接受这种解释,那么我相信以上是安全的(§3.2/ 3):
除非应用左值到右值的转换,否则
x
的名称显示为可能评估的表达式ex
的变量ex
是 odr-used (4.1)到x
产生一个不调用任何非平凡函数的常量表达式(5.20)[...]
因为在这种情况下,左值到右值的转换产生一个不调用任何函数的常量表达式(非平凡或其他),因此pi
的使用不符合odr-used
的条件,所以你没有访问一个对象。换句话说,正如您所期望的那样,它基本上将pi
视为与您使用#define pi 3.14159265358979
之类的内容相同。