QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1836|回复: 18

关于线程的一点疑问????

[复制链接]
发表于 2004-5-31 17:24:19 | 显示全部楼层 |阅读模式
在多进程应用程序中,如果某个进出退出,那么在这个进程中所用的资源都会释放掉,包括动态申请的内存
那么在多线程应用程序中又是怎么回事,请大家帮忙解释一下
发表于 2004-5-31 18:20:16 | 显示全部楼层
动态分配的内存不一定会被自动释放吧,好像要执行free,linux的机制不知道是怎样的。
多线程中,某个线程退出应该只释放属于该线程的资源。
回复

使用道具 举报

 楼主| 发表于 2004-5-31 20:55:31 | 显示全部楼层
是不一定被自动释放掉,还是一定不被自动释放掉
我用man查了那个pthread_join的帮助,发现这么一段话
When  a  joinable  thread  terminates,  its  memory  resources  (thread
       descriptor and stack) are not deallocated until another thread performs
       pthread_join on it. Therefore, pthread_join must  be  called  once  for
       each joinable thread created to avoid memory leaks.
也就是说只释放掉了文件描述符,和栈,但不知道堆有没有被释放掉,或许线程没有自己的堆,还请大家解释一下

如果不被释放掉,那各个线程的地址空间之间的关系是怎么样的
回复

使用道具 举报

发表于 2004-5-31 22:51:52 | 显示全部楼层
应该是一定不被自动释放,你man一下malloc看看。
这段话是指线程被非正常中断吧。
回复

使用道具 举报

发表于 2004-5-31 23:06:17 | 显示全部楼层
如果没有join(调用exit而不是cancel),会变成僵线程。它会保留其运行时的资源。
在该线程中用malloc得到的内存必须手动释放。线程申请的堆就像普通进程一样,你不释放,那进程终止时也不会被释放。
回复

使用道具 举报

 楼主| 发表于 2004-6-1 11:48:18 | 显示全部楼层
在进程中动态分配的内存,当进程结束后,系统应该会自动回收所有动态分配的内存吧,那如果调用了JOIN,之后,线程中申请的动态内存是否会自动释放呢
回复

使用道具 举报

发表于 2004-6-1 14:59:05 | 显示全部楼层
转贴
可能许多人对内存分配上的“栈 stack”和“堆 heap”还不是很明白。包括一些科班出身
的人也不明白这两个概念。我不想过多的说这两个东西。简单的来讲,stack上分配的内存
系统自动释放,heap上分配的内存,系统不释放,哪怕程序退出,那一块内存还是在那里
。stack一般是静态分配内存,heap上一般是动态分配内存。

由malloc系统函数分配的内存就是从堆上分配内存。从堆上分配的内存一定要自己释放。
用free释放,不然就是术语——“内存泄露”(或是“内存漏洞”)—— Memory Leak。
于是,系统的可分配内存会随malloc越来越少,直到系统崩溃。还是来看看“栈内存”和
“堆内存”的差别吧。

栈内存分配
—————
char*
AllocStrFromStack()
{
char pstr[100]&#59;

return pstr&#59;
}


堆内存分配
—————
char*
AllocStrFromHeap(int len)
{
char *pstr&#59;

if ( len <= 0 ) return NULL&#59;
return ( char* ) malloc( len )&#59;
}

对于第一个函数,那块pstr的内存在函数返回时就被系统释放了。于是所返回的char*什么
也没有。而对于第二个函数,是从堆上分配内存,所以哪怕是程序退出时,也不释放,所
以第二个函数的返回的内存没有问题,可以被使用。但一定要调用free释放,不然就是Mem
ory Leak!

在堆上分配内存很容易造成内存泄漏,这是C/C++的最大的“克星”,如果你的程序要稳定
,那么就不要出现Memory Leak。所以,我还是要在这里千叮咛万嘱付,在使用malloc系统
蛑龈叮?谑褂胢alloc系统
函数(包括calloc,realloc)时千万要小心。

记得有一个UNIX上的服务应用程序,大约有几百的C文件编译而成,运行测试良好,等使用
时,每隔三个月系统就是down一次,搞得许多人焦头烂额,查不出问题所在。只好,每隔
两个月人工手动重启系统一次。出现这种问题就是Memery Leak在做怪了,在C/C++中这种
问题总是会发生,所以你一定要小心。一个Rational的检测工作——Purify,可以帮你测
试你的程序有没有内存泄漏。

我保证,做过许多C/C++的工程的程序员,都会对malloc或是new有些感冒。当你什么时候
在使用malloc和new时,有一种轻度的紧张和惶恐的感觉时,你就具备了这方面的修养了。

对于malloc和free的操作有以下规则:

1) 配对使用,有一个malloc,就应该有一个free。(C++中对应为new和delete)
2) 尽量在同一层上使用,不要像上面那种,malloc在函数中,而free在函数外。最好在同
一调用层上使用这两个函数。
3) malloc分配的内存一定要初始化。free后的指针一定要设置为NULL。

注:虽然现在的操作系统(如:UNIX和Win2k/NT)都有进程内存跟踪机制,也就是如果你
有没有释放的内存,操作系统会帮你释放。但操作系统依然不会释放你程序中所有产生了M
emory Leak的内存,所以,最好还是你自己来做这个工作。
回复

使用道具 举报

 楼主| 发表于 2004-6-1 15:29:24 | 显示全部楼层
这个问题先暂时放一放,另外一个问题是,创建的线程和主线程,在地址空间上的关系是怎样的,比如他们各自具有各自的栈,是否所有线程都公用一个堆等等
回复

使用道具 举报

 楼主| 发表于 2004-6-1 15:42:10 | 显示全部楼层
刚才在LINUX上试了一下,写了个小程序,发现程序结束后,动态分配的内存好像都被自动回收了
回复

使用道具 举报

发表于 2004-6-1 15:42:30 | 显示全部楼层
同一进程内的所有线程用同一地址空间。
堆没有公用私用之分吧。
回复

使用道具 举报

 楼主| 发表于 2004-6-1 22:39:57 | 显示全部楼层
谢谢你的帮助,大概理解了
回复

使用道具 举报

发表于 2004-6-2 09:50:36 | 显示全部楼层
[quote:33b456db0c="quarkonics"]刚才在LINUX上试了一下,写了个小程序,发现程序结束后,动态分配的内存好像都被自动回收了[/quote]
你是怎样确定它被回收了?
回复

使用道具 举报

发表于 2004-6-2 15:14:05 | 显示全部楼层

Re: 关于线程的一点疑问????

[quote:0bfe4d2f99="quarkonics"]在多进程应用程序中,如果某个进出退出,那么在这个进程中所用的资源都会释放掉,包括动态申请的内存
那么在多线程应用程序中又是怎么回事,请大家帮忙解释一下[/quote]

基本概念要清楚阿。
由于引进了线程,linux才概念清晰了。

一个进程有一个内存空间,一个进程里的线程共享那个内存空间。
每个线程有自己的栈空间。

所以线程退出只会释放它的栈空间,而malloc是对内存空间的,所以不会释放。
进程结束的话,所有的资源都会被回收(除非操作系统有bug)。
回复

使用道具 举报

 楼主| 发表于 2004-6-2 20:38:58 | 显示全部楼层
我写了小程序动态分配4M的空间,然后用TOP查看内存使用的情况,比较笨的办法
回复

使用道具 举报

发表于 2004-6-2 22:59:42 | 显示全部楼层
既然系统会自动收回,内存泄漏是怎样产生的呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 04:38 , Processed in 0.063966 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表