C++ 静态成员函数和线程安全
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4617167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
static member functions and thread-safety
提问by Tony The Lion
Objects and variables created in a static member function are not considered 'local' as they would in a member function, so that they can now be shared amongst multiple threads right?
在静态成员函数中创建的对象和变量不像在成员函数中那样被视为“本地”,因此它们现在可以在多个线程之间共享,对吗?
Whereas if you have a member function which creates some object, this would be local to the thread and therefore it is non-shared.
而如果您有一个创建某个对象的成员函数,这将是线程的本地函数,因此它是非共享的。
Am I correct in saying this?
我这样说对吗?
回答by Michael J
Consider this class
考虑这个类
class CData
{
public:
static void func()
{
int a;
static int b;
}
int c;
static int d;
};
int main()
{
CData::func();
}
Now variable a
is local to each call of func()
. If two threads call func()
at the same time, they get different versions of a
.
现在变量a
对于func()
. 如果两个线程同时调用func()
,它们会得到不同版本的a
.
b
is a static local. The value persists between different calls of func()
. If two threads call func()
at the same time, they access the same version of b
so they might need to do synchronisation.
b
是一个静态本地。该值在 的不同调用之间保持不变func()
。如果两个线程同时调用func()
,它们访问相同的版本,b
因此它们可能需要进行同步。
c
is an instance variable; it is attached to a particular instantiation of CData. func()
cannot access c
, except with a trick I'll show below.
c
是一个实例变量;它附加到 CData 的特定实例。 func()
无法访问c
,除非我将在下面展示一个技巧。
d
is a static variable. There is one instance of d
shared between all uses of class CData so synchronisation may be necessary. It can be used easily from the static function func()
.
d
是一个静态变量。在d
类 CData 的所有使用之间有一个shared实例,因此可能需要同步。它可以很容易地从静态函数中使用func()
。
The trick used to access instance data from a static function is to pass a valid object into the function.
从静态函数访问实例数据的技巧是将有效对象传递给函数。
e.g.
例如
class CData
{
public:
static void func(CData *p)
{
int a;
static int b;
b = p->c;
}
int c;
static int d;
};
int main()
{
CData data;
CData::func(&data);
}
Hope that helps.
希望有帮助。
回答by Stephane Rolland
No you are not correct.
不,你不正确。
Objects created in a static function are notshared, and this is also the case for any normal functions.
在静态函数中创建的对象不共享,任何普通函数也是如此。
Objects can be shared though if they are declared static themselves, and it does not depends if the function is static or not.
如果对象本身被声明为静态,则对象可以共享,并且不取决于函数是否为静态。
void myFunc()
{
static MyObject o;
o.CallMethod(); // here o is shared by all threads calling myFunc
}
When an object is declared static, it is as if the object was a global variable, but only visible in the scope of the function that it is declared into.
当一个对象被声明为静态时,就好像该对象是一个全局变量,但只在它被声明到的函数范围内可见。
回答by CashCow
No you are not correct. And yes, C++ does very much overuse the word "static".
不,你不正确。是的,C++ 确实过度使用了“静态”这个词。
A static class member variable is of course a global with the class acting as a namespace scope and with some access privilege differences if it is private or protected (can only be accessed by the class).
静态类成员变量当然是一个全局变量,该类充当命名空间范围,并且如果它是私有的或受保护的(只能由类访问),则具有一些访问权限差异。
However a static class member function is just like a regular free-function (not class member) and has its own local variables every time it is called.
然而,静态类成员函数就像一个普通的自由函数(不是类成员),每次被调用时都有自己的局部变量。
The only real difference between a static class member function and a regular free-function, apart from its naming convention, is that it has access to private members of a class (and needs an external "instance" of one).
除了命名约定之外,静态类成员函数和常规自由函数之间唯一真正的区别在于它可以访问类的私有成员(并且需要一个外部“实例”)。
In addition a static class member function can be called from a template with a variable template parameter, invoking what is commonly called "compile-time polymorphism" and is commonly used in meta-programming.
此外,可以从具有可变模板参数的模板调用静态类成员函数,调用通常称为“编译时多态性”并常用于元编程的内容。
A static "local" variable in any function is a single-instance, on the other hand, is also a bit like a global and is sensitive to thread-contention issues as two threads calling the function access the same instance.
任何函数中的静态“局部”变量都是单实例,另一方面,它也有点像全局变量,并且对线程争用问题很敏感,因为调用该函数的两个线程访问同一个实例。
回答by Raphael Bossek
It does not matter if a function is static or not (class method). Only automatic variables can be seen as localto a function. If you have the address of those data, you may access it.
函数是否是静态的(类方法)并不重要。只有自动变量才能被视为函数的局部变量。如果您有这些数据的地址,您就可以访问它。
You can use e.g. thread-local storageto assign your output to a dedicated thread context.
您可以使用例如线程本地存储将您的输出分配给专用线程上下文。