函数可重入性问题,为什么说函数体内调用了malloc()或者free()的函数是不可重入的?

郑大满 2007-08-03 03:30:08
在网上看到的文章说到:
一、可重入函数
1)什么是可重入性?
可重入(reentrant)函数可以由多于一个任务并发使用,而不必担心数据错误。相反, 不可重入(non-reentrant)函数不能由超过一个任务所共享,除非能确保函数的互斥(或者使用信号量,或者在代码的关键部分禁用中断)。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。可重入函数要么使用本地变量,要么在使用全局变量时保护自己的数据。

2)可重入函数:
不为连续的调用持有静态数据。
不返回指向静态数据的指针;所有数据都由函数的调用者提供。
使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。
如果必须访问全局变量,记住利用互斥信号量来保护全局变量。
绝不调用任何不可重入函数。

3)不可重入函数:
函数中使用了静态变量,无论是全局静态变量还是局部静态变量。
函数返回静态变量。
函数中调用了不可重入函数。
函数体内使用了静态的数据结构;
函数体内调用了malloc()或者free()函数;
函数体内调用了其他标准I/O函数。
函数是singleton中的成员函数而且使用了不使用线程独立存储的成员变量 。
总的来说,如果一个函数在重入条件下使用了未受保护的共享的资源,那么它是不可重入的。

//--------------------------

我的问题:
为什么说函数体内调用了malloc()或者free()的函数是不可重入的?
是因为malloc(),free()是线程不安全的吗?
...全文
2087 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
alq974120alq 2007-08-10
  • 打赏
  • 举报
回复
噢,可能错误了,
我说成可重用的了


现在你就放心用吧,基本没多少程序会牵扯到这类问题。
alq974120alq 2007-08-10
  • 打赏
  • 举报
回复
现在C C++写出来的东西基本都是可重入的。
只要里面不过多的嵌入汇编代码。
redleaves 2007-08-10
  • 打赏
  • 举报
回复
其实可重入这个概念原本是用在中断处理函数上的,和并行有点像,但不一样.如果说一个中断过程可以在执行的过程中中止,再次进入中断而不会有错误,那么这个中断就是可重入中断.如果中断不可重入,那就要在中断过程里把中断关掉,以避免再产生新的中断,打断当前中断代码的运行.

如果只要求代码可以并行,只要保证你的代码所使用到的资源没有依赖关系,不发生冲突就可以了.至于是否使用了像malloc这种东西,其实没有什么太大的关系.虽然这里会使执行过程产生互斥,但这种冲突的机率很小.几乎可以忽略...
loops 2007-08-09
  • 打赏
  • 举报
回复
可以并行性是指真正的并行(比如双CPU),还是分时的类并行?
如果依旧是分时的类并行的话,线程安全就是可并行啊。
shgmail 2007-08-09
  • 打赏
  • 举报
回复
lddLinan 2007-08-09
  • 打赏
  • 举报
回复
线程安全和可重入是两码事,
malloc /free是线程安全的,但不是可重入的;
可重入主要体现在中断上,如果malloc的过程中发生中断(中断是锁不住的),如果在中断处理函数中有重入malloc,就会有问题
a18363939205 2021-07-31
  • 举报
回复
@lddLinan 请问,有什么问题啊?还是没能想明白
郑大满 2007-08-09
  • 打赏
  • 举报
回复
我所做的项目中,“可重入性”的问题是关注并行性。
2个线程并行运行,我所实现的线程函数体中调用了很多别人的子函数。别人的子函数当初设计的时候却没有考虑到在多线程同时被调用的情况。
我现在需要分析并重新做修改。
因此,发了一此帖。

我也认为malloc和free是线程安全的,只要2个线程不是对同一个指针进行操作,那么应该可以说是没有问题的。


To seysey():
如下代码,如果线程A和线程B他们的线程函数体都是ThreadProc。你的问题是不是说在subFun()中,*p = nInput; 最后*p用什么?
int subFun( int nInput )
{
int nResult = 0;
int* p = static_cast<int*>( malloc( sizeof(int) ) );
*p = nInput;
//....
free( p );
p = NULL;

return nResult;
}

DWORD ThreadProc( LPVOID lpParameter )
{
bool* pB = (bool*)lpParameter;
if ( *pB )
{
return subFun( 1234 );
}
else
{
return subFun( 4567 );
}
}

因为线程是有自己的调用堆栈,线程A和B分别进入subFun,都会有自己的p的。
各自用各自的。那是没有问题的。
fengyun19830512 2007-08-08
  • 打赏
  • 举报
回复
因为malloc和free不是在堆栈上的操作.比如可能出现你刚malloc了一段内存,这是中断发生了,在另一个线程中释放了这段内存导致操作失败.不知道是不是这个原因,高手指点
houdy 2007-08-08
  • 打赏
  • 举报
回复
CRT库早就支持多线程了,早就改写成"可重入"的了.
最起码VS带的CRT库和GCC带的CRT库应该已经改写成"可重入"的了.
郑大满 2007-08-08
  • 打赏
  • 举报
回复
有疑问,才请大家帮忙啊。。。。
redleaves 2007-08-08
  • 打赏
  • 举报
回复
这个可重入是指什么?是指线程安全性.还是可以并行性...
如果是后者,只要没有资源冲突,就是可并行的.
如果是前者,只要是可并行的,或着保证了访问冲突资源的唯一性时,就是线程安全的.
看样子是前者...

如果从操作系统层面上来看,可重入有点类似于后者..
从这个角度来看,说malloc和free是不可重入的.因为在PC上,内存资源是唯一的,操作系统无法同时分配/释放多块内存,但它是线程安全的...
ochinchina 2007-08-08
  • 打赏
  • 举报
回复
至少现在malloc和free是重入的了
seysey 2007-08-08
  • 打赏
  • 举报
回复
一个调用了这个程序,malloc开辟一块空间,写入了1234,另一个调用了这个程序,malloc开辟一块空间,写入4567,这时候后面代码用到这块内存用1234还是4567?
郑大满 2007-08-08
  • 打赏
  • 举报
回复
fengyun19830512()的疑惑也正是我的疑惑。。。
LoveYouJustOneDay 2007-08-04
  • 打赏
  • 举报
回复
因为malloc是不可重入的
sxcong 2007-08-03
  • 打赏
  • 举报
回复
听风就是雨,如果这个人说使用C语言是中国四大发明之一,你信吗?
mLee79 2007-08-03
  • 打赏
  • 举报
回复
那年的东东... 一半是错的 ...
taodm 2007-08-03
  • 打赏
  • 举报
回复
你看的“网文”能保证正确么?

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧