malloc线程安全吗?

10 浏览
0 Comments

malloc线程安全吗?

malloc()函数是否可重入?

0
0 Comments

在阅读的过程中,我了解到了关于malloc函数在多线程环境下是否安全的问题。某些情况下,如果使用-pthread编译,malloc函数就会变得线程安全。但是,我相信这取决于具体的实现,因为malloc是ANSI C标准的,而多线程不是。

根据gcc的文档,如果使用-pthread编译和链接程序,malloc函数在x86和AMD64架构上是线程安全的。

另一个更有见地的意见是,glibc-2.2及以上版本的{malloc,calloc,realloc,free,posix_memalign}函数是线程安全的。

然而,“我在某个地方读到...”并不是一个被接受的答案的质量标准。但是,他提供了参考链接。

需要注意的是,仅仅添加-pthreads并不能自动使malloc函数线程安全。如果在信号处理器中调用malloc函数,可能会发生各种疯狂的事情。

事实上,从信号处理器中调用malloc函数被认为是不安全的;在这方面,几乎没有什么是安全的。它在某些情况下可能工作,但在法律上和可移植性上并不合法(参见en.cppreference.com/w/c/program/signal和man7.org/linux/man-pages/man7/signal-safety.7.html)。

0
0 Comments

malloc函数是C语言中的一个内存分配函数,用于动态分配内存空间。在多线程的程序中,如果多个线程同时调用malloc函数进行内存分配,就会出现竞争条件,可能导致内存分配出错或者发生其他问题。因此,有人提出了一个问题:"is malloc reentrant?",即malloc函数是否可重入。

答案是不可重入。根据维基百科上对可重入子程序的定义,malloc函数不允许重入(例如从信号处理程序中)。并且,几乎所有版本的malloc函数都使用了锁(这使它们是线程安全的),或者使用了全局/静态变量(这使它们既不是线程安全的也不是可重入的)。

然而,上述问题中的答案并没有回答"Is malloc thread-safe?"这个完全不同的问题。对于这个问题,答案取决于你所使用的运行时库,可能还取决于你使用的编译器标志。在现代的UNIX系统上,默认情况下会得到一个线程安全的malloc函数。在Windows系统上,可以使用"/MT"、"/MTd"、"/MD"或"/MDd"标志来获取线程安全的运行时库。

可重入子程序可以使用锁,只要锁是可重入的即可。这意味着锁大致等同于递归或错误检查的互斥锁,但是在获得锁的单个原子操作中,必须保证锁结构处于一致状态,以便在获得新锁时具有单个引用。当然,你还必须处理由同一线程中的中断代码部分修改的由锁保护的状态的情况,但是可重入锁可以成为处理该问题的一个基本构件...

我认为"/MT"、"/MTd"、"/MD"等只是表示使用发布/调试/动态或静态CRT版本,并不表示malloc函数是否线程安全(它实际上调用了具有不序列化可选标志的HeapAlloc函数)。

0
0 Comments

malloc()函数是C语言中用于动态内存分配的函数。在多线程编程中,一个常见的问题是是否可以在多个线程中同时调用malloc()函数而不会导致错误或冲突。

早些时候,malloc()函数并不是线程安全的,这意味着在多个线程同时调用该函数时可能会导致内存分配错误或不一致的结果。然而,根据当前的情况,malloc()函数是线程安全的。

根据GNU C库参考手册中glibc-2.20版本(发布于2014年9月7日)的说明,malloc()函数被认为是MT-Safe(多线程安全)的。这意味着在存在其他线程的情况下,调用该函数是安全的。

然而,MT-Safe并不意味着函数是原子的,也不意味着它使用 POSIX 提供给用户的任何内存同步机制。即使按顺序调用两个MT-Safe函数也不能保证与原子执行两个函数组合的行为等效,因为其他线程中的并发调用可能会以破坏性的方式干扰。

此外,整个程序优化可能会导致函数在库接口之间进行内联时出现不安全的重排序,因此不建议在 GNU C库接口之间执行内联。然而,用户可见头文件中定义的函数设计为安全地进行内联。

,当前的状态是malloc()函数是线程安全的,但仍需注意不同线程之间的并发调用可能会产生意外的结果。为了保证安全性,不建议在整个程序优化的情况下使用内联函数。

解决此问题的方法是在多线程编程中使用malloc()函数时,确保对该函数的并发调用不会产生破坏性的干扰。这可以通过使用互斥锁或其他同步机制来实现,以确保每个线程在访问malloc()函数时是独立的。这样可以避免并发调用导致的错误和不一致性。

0