12

我在读这个:http ://en.wikipedia.org/wiki/Thread_safety

以下函数是线程安全的吗?

void foo(int y){
    int * x = new int[50];
    /*...do some stuff with the allocated memory...*/
    delete [] x;
}

在文章中它说为了线程安全,您只能使用堆栈中的变量。真的吗?为什么?上述函数的后续调用不会在其他地方分配内存吗?

编辑:啊。看起来我误读了文章的这一部分:

子程序是可重入的,因此是线程安全的,如果

  • 它使用的唯一变量来自堆栈

(我认为它的意思是

子程序是可重入的,因此是线程安全的,当且仅当

  • 它使用的唯一变量来自堆栈

,根据下面的答案,情况并非如此)

4

3 回答 3

13

如果您在支持多线程的环境中进行编码,那么您可以非常确定new它是线程安全的。

虽然内存在堆上,但指向它的指针却在栈上。只有您的线程拥有指向此内存的指针,因此不存在并发修改的风险 - 没有其他线程知道要修改内存的位置。

如果您将此指针传递给另一个线程,然后该线程将与您的原始(或另一个)线程同时修改此内存,您只会遇到线程安全问题。

于 2010-05-17T00:01:11.307 回答
2

它并不是说您只能使用堆栈变量,而是说使用堆变量“表明需要仔细检查它是否不安全”。

new并且delete通常以线程安全的方式实现(虽然不确定标准是否保证)所以你上面的代码可能会很好。

加上通常使用std::vector而不是手动分配数组的建议,但我假设您仅提供了一个示例:)

于 2010-05-17T00:00:11.567 回答
1

new 和 delete 可能是线程安全的,也可能不是线程安全的。它们可能是,但这取决于实现。请参阅: Linux 和 gcc 4 中的 C++ 新运算符线程安全

为了线程安全,函数必须要么使用堆栈变量,要么将其对其他资源的访问与其他线程同步。只要从不同线程调用时对 new 的单独调用在堆上分配不同的空间,就可以了。

于 2010-05-16T23:58:43.147 回答