代码之家  ›  专栏  ›  技术社区  ›  Cam

具有堆分配内存的线程安全性

  •  12
  • Cam  · 技术社区  · 15 年前

    我在读这个: 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 回复  |  直到 15 年前
        1
  •  12
  •   sth    15 年前

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

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

    只有当您将此指针传递给另一个线程时,线程安全才会出现问题,该线程将同时修改此内存,同时修改原始(或另一个)线程。

        2
  •  2
  •   Peter    15 年前

    它并没有说您只能使用堆栈变量,而是说使用堆变量“意味着需要仔细检查以确定它是否不安全”。

    new delete 通常是以线程安全的方式实现的(但不确定标准是否保证如此),因此上面的代码可能会很好。

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

        3
  •  1
  •   Community CDub    7 年前

    新建和删除可能是线程安全的,也可能不是线程安全的。它们可能是,但这取决于实现。见: C++ new operator thread safety in linux and gcc 4

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