我做了以下推理,请告诉我它的错误(或正确):
“如果内联函数复制了函数被调用的位置的代码,那么静态和局部变量就会被调用它的每个函数重复,如果只有一个运行该函数的线程在同一个函数中调用内联函数时间,然后代码是线程安全的“。
“而且,如果它对静态变量和全局变量没有帮助,那么它是否会创建临时变量的代码?”
由于
答案 0 :(得分:28)
答案 1 :(得分:25)
当您将函数声明为内联时,它只是对编译器的提示。静态变量在语言中有明确的定义。如果编译器内联函数,则仍然有义务保持函数的所有实例之间共享的静态变量。因此,它们将保持全球性并且必须在MT环境中受到保护。
对于局部变量,除非它们在函数之外使用,否则无论是否内联函数,它们都是线程安全的。
答案 2 :(得分:6)
每个线程都有自己的本地对象副本,因此无论是否内联都不会出现任何与线程相关的问题。
但是如果你正在访问类的静态或成员变量,那么与多线程相关的所有问题(破坏变量,丢失更新......)仍将存在,无论它是否是内联的。< / p>
答案 3 :(得分:3)
内联和线程安全是正交的,即不相关的概念。
考虑以下功能:
int factorial(const int n) { if (n <= 1) { return 1; } return factorial(n - 1); }
此函数无法内联,因为它是递归的,但它完全是线程安全的。
int factorial_2(int n) { int Result = 1; while (n > 1) { Result *= n--; } return Result; }
这个函数可以由编译器内联,并且仍然是完全线程安全的。
int RefCount; void DecRef() { --RefCount; }
无论编译器是否内联,此函数都不是线程安全的。
答案 4 :(得分:3)
以前版本的C ++(以及当前版本的C)不承认线程的概念。它不是标准的一部分。所以依靠一些编译器优化来使你的代码线程安全不是一个好主意。
答案 5 :(得分:2)
有(或许是)错误编译器,它们为包含函数的每个内联复制静态变量。这不是预期的行为。
使用标准兼容的编译器,无论内联如何,都可以保证每个静态变量都有一个实例,并且必须自己处理线程安全。
答案 6 :(得分:2)
Thread safety与内联无关。仅仅因为每个线程执行相同代码的副本并不能使访问共享数据变得安全。在开始多线程编程之前,请务必阅读Thread safety。
答案 7 :(得分:2)
如果我是你,我不会在内联函数中使用静态变量。较旧版本的C ++标准需要与当前版本不同的含义。
答案 8 :(得分:1)
内联对函数是否是线程安全没有影响。例如:
inline void doTheThing()
{
int a = 42; // this is thread safe, but it would be anyway
vector<int> * answers = getTheAnswers(); // this is not thread safe
}
getTheAnswers()指向的向量访问不是线程安全的,因为没有代码阻止任何其他线程执行代码。使函数内联不会阻止doTheThing()同时被多个线程调用。为了使doTheThing()线程安全,您需要确保它不是并行调用的,或者您访问的任何共享(非本地)数据都受到保护。
答案 9 :(得分:0)
完全没有。
为了保证线程安全,函数需要相对于函数的任何实例(包括其自身)是线程安全的;多个线程可以同时执行内联函数的同一个实例。
因此,即使编译器完成了你的建议(它不应该像其他人所说的那样),那仍然不会使它成为线程安全的。
答案 10 :(得分:-2)
(正常和内联)函数中的所有静态变量都进入堆。堆 NOT THREAD SAFE 。