使用堆分配的内存线程安全

时间:2010-05-16 23:54:53

标签: c++ stack thread-safety heap

我正在读这个: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;
}

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

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

  

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

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

(我认为是

  

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

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

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

3 个答案:

答案 0 :(得分:12)

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

虽然内存在堆上,但指向它的指针位于堆栈上。只有你的线程有指向这个内存的指针,所以不存在并发修改的风险 - 没有其他线程知道内存在哪里修改它。

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

答案 1 :(得分:2)

它并没有说你只能使用堆栈变量,它说使用堆变量“建议需要仔​​细检查以确定它是否不安全”。

newdelete通常以线程安全的方式实现(不确定标准是否保证),因此上面的代码可能没问题。

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

答案 2 :(得分:1)

new和delete可能是也可能不是线程安全的。它们可能是,但这是依赖于实现的。看到: C++ new operator thread safety in linux and gcc 4

要保证线程安全,函数必须使用堆栈变量或将其对其他资源的访问权限与其他线程同步。只要从不同的线程调用时,单独调用new就会在堆上分配不同的空间,那么你应该没问题。