Chinaunix

标题: 求助 c/c++ 线程编程问题(linux下) [打印本页]

作者: sevendays    时间: 2005-12-12 09:26
标题: 求助 c/c++ 线程编程问题(linux下)
写了一段应用程序,发现有内存泄漏。把程序分开测试,发现问题出在线程资源这一块,请各位大虾帮忙指点一二,最好能编译测试一下,我已经测试一个多星期了,就是没有找出原因,初学者,请多关照:)
/**************pthreadtest2.cpp ****************/
#include <stdio.h>
#include <iostream>
#include <vector>
#include <semaphore.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>

using namespace std;

void* sendMsgs(void *arg)
{
        pthread_exit(NULL);
}

int main(void)
{
                sleep(30);       //此处用pmap 查看到mapped内存2280k
        
        unsigned int i = 0;        
               
                 //循环体内执行过程中通过pmap 查看到mapped内存14572k
        while( i < 65000)
        {
                i ++;
                int flag = 0;
                pthread_attr_t pthread_attr;
                pthread_attr_init(&pthread_attr);
                pthread_attr_setdetachstate(&pthread_attr,PTHREAD_CREATE_JOINABLE);                pthread_t threadSend;
                if( (flag = pthread_create(&threadSend,&pthread_attr,&sendMsgs,NULL) != 0 ) )
                {
                        cout << "create Error(threadSend):" << flag << endl;
                        break;
                }
               
                pthread_join(threadSend,NULL);
                pthread_attr_destroy(&pthread_attr);
        }        
        
        cout << "waiting ..." << endl;
        sleep(30);  //此处 mapped内存14572k
        
        return -1;
}

如果这个sendMsg内加入 string aa = "dfaaaaaadsfsd..."等等,那么内存吃得更多。
而且发现,吃掉内存的多少跟循环次数有关系,但不是线性关系;比如说循环1次和1000次他们吃掉的内存同样是6M左右,但是增加到某个数,一下就到了8M.
请各位帮忙测试测试,为什么会是这样的结果。
作者: sevendays    时间: 2005-12-12 09:49
标题: 没人帮忙看看啊,我实在是无法继续了,一直找不到答案,有经验的多帮忙啊:)
自己顶,不然沉了
作者: benjiam    时间: 2005-12-12 10:13
系统每次不是一次就分配那么多内存给你 应该按找2^n 给你 提高效率吧
string aa = "dfaaaaaadsfsd..."等等,那么内存吃得更多。

改成 static string aa = "dfaaaaaadsfsd..." 应该就不会分配那么多了

为什么会一下子用那么多内存  我猜得 是因为现在cpu 太快了 可以create 很多线程
你这样 很有可能崩溃掉得
因主线程可能迅速建立很多线程  子线程还没开始运行 已经建立了很多
作者: yixiao_wang    时间: 2005-12-12 10:28
pthread_attr ,这个玩意是需要释放的吧!!!
作者: sevendays    时间: 2005-12-12 11:19
标题: 回复
1〉每次循环体内都是主先程pthread_join等待线程结束了啊,不存在创建了很多线程吧?
2〉每次循环体内都通过 pthread_attr_destroy(&pthread_attr);释放了pthread_attr
采用static是可以缓解,但是这是为什么呢?pthread_exit()的时候没有释放线程的资源吗?
查遍了资料,没有找到这个疑问的答案。
作者: linternt    时间: 2005-12-12 11:47
线程退出时加下打印信息,可以写到文件里,加上线程号pthread_self()
可是试着休眠一会,看主程序执行情况,或者加入一些打印信息,比如在pthread_join()后等等
作者: sevendays    时间: 2005-12-12 12:39
标题: 好,抽空测试一下
3q
作者: yixiao_wang    时间: 2005-12-12 15:50
呵呵,我刚才测试一下,那个多出来的10Md的内存是linux在创建线程时候缺省的,线成大小,这个大小在solaris缺省时1M,由于你的程序没有进行其余的内存操作,所以你虽然循环了,65000次但实际上,你现在的处理跟本没有涉及到并发,也就是使还是在一个线程空间,循环使用的,对你说的sring str="aaa",这个问题可能是由于linux  write&copy的问题,对于这个10M的内存没有被立刻释放,我感觉可能是这个内存是在stack上分配,所以释放的时间可能是由于系统确定。总的来说这样处理没有问题。
作者: kukoo    时间: 2005-12-12 16:13
标题: 回复 8楼 yixiao_wang 的帖子
在linux上试了一下,没觉得有问题:
#cat /proc/26333/status
Name:   a.out
State:  S (sleeping)
Tgid:   26333
Pid:    26333
PPid:   26088
TracerPid:      0
Uid:    0       0       0       0
Gid:    0       0       0       0
FDSize: 256
Groups: 0 1 2 3 4 6 10
VmSize:     2576 kB
VmLck:         0 kB
VmRSS:       732 kB
VmData:      292 kB
VmStk:         8 kB
VmExe:         4 kB
VmLib:      2208 kB
SigPnd: 0000000000000000
SigBlk: 0000000080000000
SigIgn: 0000000000000000
SigCgt: 0000000380000000
CapInh: 0000000000000000
CapPrm: 00000000fffffeff
CapEff: 00000000fffffeff

# cat /proc/26333/status
Name:   a.out
State:  S (sleeping)
Tgid:   26333
Pid:    26333
PPid:   26088
TracerPid:      0
Uid:    0       0       0       0
Gid:    0       0       0       0
FDSize: 256
Groups: 0 1 2 3 4 6 10
VmSize:     4632 kB
VmLck:         0 kB
VmRSS:       800 kB
VmData:     2348 kB
VmStk:         8 kB
VmExe:         4 kB
VmLib:      2208 kB
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000380000000
CapInh: 0000000000000000
CapPrm: 00000000fffffeff
CapEff: 00000000fffffeff

#cat /proc/26333/status
Name:   a.out
State:  S (sleeping)
Tgid:   26333
Pid:    26333
PPid:   26088
TracerPid:      0
Uid:    0       0       0       0
Gid:    0       0       0       0
FDSize: 256
Groups: 0 1 2 3 4 6 10
VmSize:     2588 kB
VmLck:         0 kB
VmRSS:       848 kB
VmData:      304 kB
VmStk:         8 kB
VmExe:         4 kB
VmLib:      2208 kB
SigPnd: 0000000000000000
SigBlk: 0000000080000000
SigIgn: 0000000000000000
SigCgt: 0000000380000000
CapInh: 0000000000000000
CapPrm: 00000000fffffeff
CapEff: 00000000fffffeff
作者: sevendays    时间: 2005-12-12 16:23
标题: 谢谢楼上的回复,我再侧测,我的测试结果让我还在怀疑
"65000次但实际上,你现在的处理跟本没有涉及到并发,也就是使还是在一个线程空间,循环使用的"
我的这个测试程序的出发点真正此处啊,没有并发,按道理应该不会增长的阿,你别用soliras,linux的线程机制跟soliars不同,linux线程是轻量级进程,用户级别的
作者: sevendays    时间: 2005-12-12 16:27
标题: 回复 9楼 kukoo 的帖子
呵呵,找你这样确实没问题,可为什么我用pmap看的就一直是那么多呢?难道pmap有问题?我也cat一下进程文件看看

谢谢
作者: sevendays    时间: 2005-12-12 16:34
标题: 回复 9楼 kukoo 的帖子
pmap没有问题,难道是系统问题?
这是我cat出来的状态
Name:   pthreadtest2.ex
State:  S (sleeping)
Tgid:   14883
Pid:    14883
PPid:   12949
TracerPid:      0
Uid:    500     500     500     500
Gid:    500     500     500     500
FDSize: 256
Groups: 500
VmSize:     6380 kB
VmLck:         0 kB
VmRSS:       852 kB
VmData:     4148 kB
VmStk:         8 kB
VmExe:         4 kB
VmLib:      2168 kB
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 8000000000000000
SigCgt: 0000000080000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
一直都没减少过,唉!
作者: sevendays    时间: 2005-12-19 16:08
标题: 问题基本上已经解决,gcc所带的线程库问题,继续测试中,谢谢大家
问题基本上已经解决,gcc所带的线程库问题,继续测试中,谢谢大家
作者: Alligator27    时间: 2005-12-19 21:58
LZ能否说说, 线程库有什么问题? 哪个版本的libpthread. 用什么方法测试?
谢谢.
作者: sevendays    时间: 2005-12-20 09:58
标题: 大概如下
我这环境是linux 2.4(redhat) + gcc3.2.2
目前还没有正式结果,但测试到的现象如下
1> 对于子线程内使用的栈空间,如果不在创建子线程之前申请好,并且自己管理,那么在子线程pthread_exit和pthread_join调用之后,系统默认的子线程栈还是同样没有释放(可能是要等到整个进程退出之后,管理线程才回收)
2> 对于子线程内部的堆空间,比如string类对象,如果不在改对象销毁之前显式调用~string()函数,那么堆空间也不会释放
3> 不用pthread_exit退出线程,用return 的话,效果好一点,但没有仔细测试。
基于这上面的三点,我都不愿意再测试了,准备升级gcc再来看看,我的pm说是linux缓存机制问题,但是具体都没有去测试查资料,所以我准备一个个排查。我刚进这公司不久,手上只有一个测试机,升级gcc得请示上面...大家如果测试过的,把gcc版本linux版本贴出来,我估计就是线程的实现问题
作者: Alligator27    时间: 2005-12-20 10:29
原帖由 sevendays 于 2005-12-20 09:58 发表
我这环境是linux 2.4(redhat) + gcc3.2.2
目前还没有正式结果,但测试到的现象如下
1> 对于子线程内使用的栈空间,如果不在创建子线程之前申请好,并且自己管理,那么在子线程pthread_exit和pthread_join调用 ...

我认为,你没有证据说线程库有问题. 你的测试程库就说明了这点.

(1) 你的PM说得对, 子线程内使用的栈空间是缓存的.

(2) 子线程没有内部的堆空间, 所有的堆上的东西都是进程的. 所有线程共享. string不需要显式调用~string()函数来释放其使用的堆空间.

(3) pthread_exit和return对你没区别.

升级gcc不会有改变, 建仪找找别的原因.
作者: sevendays    时间: 2005-12-20 15:48
标题: 回复 16楼 Alligator27 的帖子
1〉第一条 linux缓存机制只查到比较笼统的原理,这个我没有深入去了解
2〉第二条 我在函数内部string 对象的堆是在进程上的,所以如果不显式释放,也就说要等到进程结束才释放
3〉return 和 pthread_exit 是一样,但我不理解这个测试结果
  如果调用return,但对里面的string对象不调用~string(),那么内存正常
  如果调用pthread_exit(NULL),但对里面的string调用~string 那么内存正常
  如果调用pthread_exit(NULL),但不掉用~string(),那么每次循环都会吃掉我给string里面的1M左右的空间

当然,这在进程结束的时候能释放,但为什么会这样?如果你给出权威资料以及测试结果,我信

从你的回贴我要鄙视所谓的牛人们,经验是比我丰富,知识面和深度是比我强,你泛泛而谈,自以为是的建议,为什么我就不能怀疑gcc版本太低,你这样测试过?你就敢这么肯定?
作者: renstone921    时间: 2005-12-20 17:13
to 楼上:

2〉第二条 我在函数内部string 对象的堆是在进程上的,所以如果不显式释放,也就说要等到进程结束才释放

是谁告诉你函数内部的string对象是在进程堆里面创建的?

只要你不是用new delete分配和释放string对象并且只要它不是一个静态对象,那么它就是基于堆栈的。希望你把heap和stack两个概念区分清楚;

当你使用new和delete进行对象分配时,是在堆内为对象分配内存。比如这样
string* helloStr = new string("hello");
...
delete helloStr;
进程内所有线程共享其所属进程的堆资源。

当你在线程函数里使用
string helloStr = "hello";时,"hello"这个字符串被分配在进程的常量数据区内。
而helloStr则被分配在线程的堆栈上,编译器会产生调用形如string(const char* str)形式的构造函数的代码,helloStr对象的data数据成员被初始化为一个在堆内动态分配的被初始化为"hello"字符串的地址。
当线程退出时,所有基于堆栈分配的资源都会被销毁,编译器会产生代码调用string::~string()来保证销毁为string类对象所分配的资源。

进程内每个线程都有其私有的堆栈资源。

所以你所说的
如果调用return,但对里面的string对象不调用~string(),那么内存正常

这条正确,编译器会对自动变量调用析构函数

如果调用pthread_exit(NULL),但对里面的string调用~string 那么内存正常
这条是胡说。你显式的调用一次析构函数,然后编译器产生代码调用一次析构函数,连续两次调用delete,如果析构函数在释放堆资源后,立即将指针成员置为NULL,不会出错。但如果连续针对某一指针调用delete,这时,堆结构已经破坏了。没有立即出错并不代表你的程序是正确的。


如果调用pthread_exit(NULL),但不掉用~string(),那么每次循环都会吃掉我给string里面的1M左右的空间
使用gcc -v 看一下你的编译器里面有没有enable-thread选项,如果有,不可能出现这种问题。如果你非要用一个根本不支持多线程的版本来编译一个多线程程序的话,进程的堆结构已经不知道被破坏成什么样子了。

从你的回贴我要鄙视所谓的牛人们,经验是比我丰富,知识面和深度是比我强,你泛泛而谈,自以为是的建议,为什么我就不能怀疑gcc版本太低,你这样测试过?你就敢这么肯定?

你比牛人要牛多了。牛人一般都是谨小慎微的先怀疑自己,狂牛先怀疑编译器。自你提出问题到现在,你自己做了什么测试,得到了什么结论?什么叫做"泛泛而谈,自以为是的建议"?连别人的正确建议都看不明白的狂牛懂不懂什么叫尊重别人。

做为一个成年人,把权力和义务分清楚。在论坛里,没有人有义务来帮你。如果遇到的都是像你这样的,我宁愿一边喝茶一边看笑话。
作者: sevendays    时间: 2005-12-21 16:22
标题: 回复 18楼 renstone921 的帖子
楼上的哥们,你仔细看清楚了,别动不动就摆出一付教训人的样子。
1〉我的意思是函数内string 对象里面的堆空间申请,而不是对象本身。这些基本的东西我就不跟你扯了,你了解得很透彻,但我未必没读过书,所以轮不到你头脑发热来教训俺
2> 你的这句话
====================================
如果调用pthread_exit(NULL),但对里面的string调用~string 那么内存正常
这条是胡说。你显式的调用一次析构函数,然后编译器产生代码调用一次析构函数,连续两次调用delete,如果析构函数在释放堆资源后,立即将指针成员置为NULL,不会出错。但如果连续针对某一指针调用delete,这时,堆结构已经破坏了。没有立即出错并不代表你的程序是正确的。
====================================
你说对了一半,说错了一半。编译器会调用析构函数没错,可关键编译器在什么时候调用析构函数?你敢肯定所有编译器都一样么?我的测试结果告诉我(linux redhat9.0+gcc 3.2.2环境下) C++对象超出他定义范围时,编译器自动调用析构函数,可现在问题就出在编译器并没有在pthread_exit(NULL)之前调用过析构函数!而当注释掉pthread_exit之后,则真正调用了析构函数(目前我的猜测是编译器自动调用析构函数应该是在goto,return,右大括符(})之前调用);所以你说的我在pthread_exit(NULL)之前显式调用string::~string()函数所以不会存在多次delete,废话不多说,我附上我的测试程序,您老人家倒杯茶回家慢慢测试去吧,记得gcc环境相同,别强词夺理,动不动胡说,动动手,再发言。中科院都说了,院士只代表在某方面做过杰出贡献,并不代表他在某方面是权威,尊重事实,尊重科学
3〉===牛人一般都是谨小慎微的先怀疑自己,狂牛先怀疑编译器。==对于您老的这句话,俺不懂,俺啥都不是,就想让程序能完成应该完成的工作,结果不对,我就需要不停的测试。这话您收回去吧,我这个问题已经测试好久了,本来是一个通信程序,发现内存泄漏,第一步就是花了大量时间测试自己的协议类是否有内存泄漏,然后测试自己的闲程框架,再后来查了好多资料才怀疑编译器。不过你怎么说都跟我没关系,我不聪明,做事比较傻,牛人谈不上,如门级程序员都不算,但我会实事求是,动手测试,结果才是最重要的
4〉=======做为一个成年人,把权力和义务分清楚。在论坛里,没有人有义务来帮你==== 这话俺不同意
论坛里面无所谓帮不帮,什么叫分享,什么叫共同讨论,什么叫共同测试,什么共同解决问题,这是我最喜欢的东西,动不动帮助、教育,俺就看不惯!如果你觉得这叫帮助我,你回家喝茶看自己笑话去吧!别来玷污我的心情!如果你把这里的每个问题当作一起解决、动手测试,或者说更加提高自身的编程修养,那么我就道歉,不好意思,说话比较冲,请多多包含。

下面附上测试程序,g++ 编译之后麻烦 通过./a.out >> mem.log来执行,至于程序怎么跑的,自己看吧
==================================================================
//不进行通信,直接运行空循环体
#include <stdio.h>
#include <iostream>
#include <vector>
#include <semaphore.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>

using namespace std;


#define _MAXMASSAGECOUNT_ 1024*64

#define _STACK_SIZE_ 2UL*1024UL*1024UL

//事务条目
#define _AFFAIR_COUNT_ 5

#define _PHTREAD_DETCH_ PTHREAD_CREATE_JOINABLE

void exitFuction()
{
        cout << "exit...." << endl;       
}

class myTest
{
        public:               
                myTest()
                {
                        m_buf = new char[1024*1024];
                        memset(m_buf,0x0,1024*1024);
                        memset(m_buf,'a',1024*1024-1);
                }
               
                ~myTest()
                {
                        if( m_buf != NULL )
                        {
                                delete[] m_buf;       
                        }
                       
                        cout << "~myTest() is called" << endl;
                }
       
        protected:
                char *m_buf;
};


//输出当前进程内存信息
void writeStatus()
{
        if( getpid() <= 0 )
        {
                return;
        }
       
        char cmd[128];       
        memset(cmd,0x0,12;       
        sprintf(cmd,"/bin/cat /proc/%d/status",getpid());
        cout << "=========" << cmd << "=========" << endl;       
        system(cmd);       
        return;       
}

void* sendMsgs(void *arg)
{
        cout << "child pthread start" << endl;
       
        myTest getTest;               
       
       
        char buf[1024*1024];
        memset(buf,0x0,1024*1024);
        memset(buf,'a',1024*1024 - 1 );       
        writeStatus();
        cout << "child end" << endl;       
        pthread_exit(NULL); //此处与return 轮回注释来测试是否调用了myTest::~myTest函数
        //return NULL;
}

int main()
{
        atexit(&exitFuction);
       
        cout << "pragram started...." << endl;       
       
        writeStatus();       
                       
        unsigned int i = 0;
       
        /*
        //测试进程内存空间
        while( i < _AFFAIR_COUNT_ )
        {
                i ++;
                cout << "\t" << i << ".fork  start For" << endl;
                writeStatus();
               
                pid_t mypid = fork();
                if( mypid > 0 )
                {
                        //父进程
                        cout << "Father:fork good: " << mypid  <<  endl;
                        cout << "wating Son...." << endl;
                        waitpid(mypid,NULL,0);
                        writeStatus();
                }
                else if( mypid == 0 )
                {
                        //子进程
                        cout << "========Son start.....========" << endl;
                        writeStatus();
                        int j = 0;
                        string goodstr = "";
                        while( j < _MAXMASSAGECOUNT_ )
                        {
                                goodstr += "abcfefdasfadsdasffffffffffffffffafffffffffffffffffdaaaaaaaaafds";
                                j ++;
                        }
                        cout << "======================" << endl;
                        writeStatus();
                        cout << "=======Son end=========" << endl;
                                               
                        exit(0);       
                }
                else
                {
                        cout << " fork failture!" << strerror(errno) << endl;       
                }
        }       
       
        i = 0;
       
        cout << "fork end,started pthread... " << endl;
        writeStatus();
       
        */
       
        //测试线程内存空间
        while( i < _AFFAIR_COUNT_ )
        {
                cout << i << endl;
                writeStatus();
                               
                i ++;
                int flag = 0;
                pthread_attr_t pthread_attr;
                pthread_attr_init(&pthread_attr);
                void * addr = NULL;
                addr = malloc(_STACK_SIZE_);
                memset(addr,0x0,_STACK_SIZE_);
                //pthread_attr_setdetachstate(&pthread_attr,_PHTREAD_DETCH_);
                pthread_attr_setstack(&pthread_attr,addr,_STACK_SIZE_);
                pthread_t threadSend;
                if( (flag = pthread_create(&threadSend,&pthread_attr,&sendMsgs,NULL) != 0 ) )
                {
                        cout << "create Error(threadSend):" << flag << endl;
                        free(addr);
                        pthread_attr_destroy(&pthread_attr);
                        break;
                }               
               
                if( pthread_join(threadSend,NULL) == 0 )
                {
                        cout << "child exit good" << endl;       
                }
                else
                {
                        cout << "child exit failture" << endl;       
                }
               
                free(addr);               
                pthread_attr_destroy(&pthread_attr);
                                               
        }
       
       
        cout << "waiting ..." << endl;
        writeStatus();
       
        return -1;
}
作者: Alligator27    时间: 2005-12-22 11:28
原帖由 sevendays 于 2005-12-21 16:22 发表
楼上的哥们,你仔细看清楚了,别动不动就摆出一付教训人的样子。
1〉我的意思是函数内string 对象里面的堆空间申请,而不是对象本身。这些基本的东西我就不跟你扯了,你了解得很透彻,但我未必没读过书,所以轮不 ...


ok, fair enough. 这是我的测试结果. 我的机器是: Redhat AS3, Linux2.4.21 gcc3.2.3


  1. pragram started....
  2. =========/bin/cat /proc/27332/status=========
  3. Name:        a.out
  4. State:        S (sleeping)
  5. Tgid:        27332
  6. Pid:        27332
  7. PPid:        27260
  8. TracerPid:        0
  9. Uid:        547        547        547        547
  10. Gid:        507        507        507        507
  11. FDSize:        64
  12. Groups:        507
  13. VmSize:            9908 kB
  14. VmLck:               0 kB
  15. VmRSS:             944 kB
  16. VmData:             148 kB
  17. VmStk:             804 kB
  18. VmExe:               8 kB
  19. VmLib:            3760 kB
  20. SigPnd:        0000000000000000
  21. ShdPnd:        0000000000000000
  22. SigBlk:        0000000000010000
  23. SigIgn:        0000000000000006
  24. SigCgt:        0000000080000000
  25. CapInh:        0000000000000000
  26. CapPrm:        0000000000000000
  27. CapEff:        0000000000000000
  28. 0
  29. =========/bin/cat /proc/27332/status=========
  30. Name:        a.out
  31. State:        R (running)
  32. Tgid:        27332
  33. Pid:        27332
  34. PPid:        27260
  35. TracerPid:        0
  36. Uid:        547        547        547        547
  37. Gid:        507        507        507        507
  38. FDSize:        64
  39. Groups:        507
  40. VmSize:            9908 kB
  41. VmLck:               0 kB
  42. VmRSS:             976 kB
  43. VmData:             148 kB
  44. VmStk:             804 kB
  45. VmExe:               8 kB
  46. VmLib:            3760 kB
  47. SigPnd:        0000000000000000
  48. ShdPnd:        0000000000000000
  49. SigBlk:        0000000000010000
  50. SigIgn:        0000000000000006
  51. SigCgt:        0000000080000000
  52. CapInh:        0000000000000000
  53. CapPrm:        0000000000000000
  54. CapEff:        0000000000000000
  55. child pthread start
  56. =========/bin/cat /proc/27332/status=========
  57. Name:        a.out
  58. State:        S (sleeping)
  59. Tgid:        27332
  60. Pid:        27332
  61. PPid:        27260
  62. TracerPid:        0
  63. Uid:        547        547        547        547
  64. Gid:        507        507        507        507
  65. FDSize:        64
  66. Groups:        507
  67. VmSize:           13120 kB
  68. VmLck:               0 kB
  69. VmRSS:            4092 kB
  70. VmData:            3360 kB
  71. VmStk:             804 kB
  72. VmExe:               8 kB
  73. VmLib:            3760 kB
  74. SigPnd:        0000000000000000
  75. ShdPnd:        0000000000000000
  76. SigBlk:        0000000000000000
  77. SigIgn:        0000000000000006
  78. SigCgt:        0000000080000000
  79. CapInh:        0000000000000000
  80. CapPrm:        0000000000000000
  81. CapEff:        0000000000000000
  82. child end
  83. ~myTest() is called
  84. child exit good
  85. 1
  86. =========/bin/cat /proc/27332/status=========
  87. Name:        a.out
  88. State:        S (sleeping)
  89. Tgid:        27332
  90. Pid:        27332
  91. PPid:        27260
  92. TracerPid:        0
  93. Uid:        547        547        547        547
  94. Gid:        507        507        507        507
  95. FDSize:        64
  96. Groups:        507
  97. VmSize:           10040 kB
  98. VmLck:               0 kB
  99. VmRSS:            1056 kB
  100. VmData:             280 kB
  101. VmStk:             804 kB
  102. VmExe:               8 kB
  103. VmLib:            3760 kB
  104. SigPnd:        0000000000000000
  105. ShdPnd:        0000000000000000
  106. SigBlk:        0000000000010000
  107. SigIgn:        0000000000000006
  108. SigCgt:        0000000080000000
  109. CapInh:        0000000000000000
  110. CapPrm:        0000000000000000
  111. CapEff:        0000000000000000
  112. child pthread start
  113. =========/bin/cat /proc/27332/status=========
  114. Name:        a.out
  115. State:        S (sleeping)
  116. Tgid:        27332
  117. Pid:        27332
  118. PPid:        27260
  119. TracerPid:        0
  120. Uid:        547        547        547        547
  121. Gid:        507        507        507        507
  122. FDSize:        64
  123. Groups:        507
  124. VmSize:           13120 kB
  125. VmLck:               0 kB
  126. VmRSS:            4136 kB
  127. VmData:            3360 kB
  128. VmStk:             804 kB
  129. VmExe:               8 kB
  130. VmLib:            3760 kB
  131. SigPnd:        0000000000000000
  132. ShdPnd:        0000000000000000
  133. SigBlk:        0000000000000000
  134. SigIgn:        0000000000000006
  135. SigCgt:        0000000080000000
  136. CapInh:        0000000000000000
  137. CapPrm:        0000000000000000
  138. CapEff:        0000000000000000
  139. child end
  140. ~myTest() is called
  141. child exit good
  142. 2
  143. =========/bin/cat /proc/27332/status=========
  144. Name:        a.out
  145. State:        R (running)
  146. Tgid:        27332
  147. Pid:        27332
  148. PPid:        27260
  149. TracerPid:        0
  150. Uid:        547        547        547        547
  151. Gid:        507        507        507        507
  152. FDSize:        64
  153. Groups:        507
  154. VmSize:           10040 kB
  155. VmLck:               0 kB
  156. VmRSS:            1056 kB
  157. VmData:             280 kB
  158. VmStk:             804 kB
  159. VmExe:               8 kB
  160. VmLib:            3760 kB
  161. SigPnd:        0000000000000000
  162. ShdPnd:        0000000000000000
  163. SigBlk:        0000000000010000
  164. SigIgn:        0000000000000006
  165. SigCgt:        0000000080000000
  166. CapInh:        0000000000000000
  167. CapPrm:        0000000000000000
  168. CapEff:        0000000000000000
  169. child pthread start
  170. =========/bin/cat /proc/27332/status=========
  171. Name:        a.out
  172. State:        S (sleeping)
  173. Tgid:        27332
  174. Pid:        27332
  175. PPid:        27260
  176. TracerPid:        0
  177. Uid:        547        547        547        547
  178. Gid:        507        507        507        507
  179. FDSize:        64
  180. Groups:        507
  181. VmSize:           13120 kB
  182. VmLck:               0 kB
  183. VmRSS:            4136 kB
  184. VmData:            3360 kB
  185. VmStk:             804 kB
  186. VmExe:               8 kB
  187. VmLib:            3760 kB
  188. SigPnd:        0000000000000000
  189. ShdPnd:        0000000000000000
  190. SigBlk:        0000000000000000
  191. SigIgn:        0000000000000006
  192. SigCgt:        0000000080000000
  193. CapInh:        0000000000000000
  194. CapPrm:        0000000000000000
  195. CapEff:        0000000000000000
  196. child end
  197. ~myTest() is called
  198. child exit good
  199. 3
  200. =========/bin/cat /proc/27332/status=========
  201. Name:        a.out
  202. State:        S (sleeping)
  203. Tgid:        27332
  204. Pid:        27332
  205. PPid:        27260
  206. TracerPid:        0
  207. Uid:        547        547        547        547
  208. Gid:        507        507        507        507
  209. FDSize:        64
  210. Groups:        507
  211. VmSize:           10040 kB
  212. VmLck:               0 kB
  213. VmRSS:            1056 kB
  214. VmData:             280 kB
  215. VmStk:             804 kB
  216. VmExe:               8 kB
  217. VmLib:            3760 kB
  218. SigPnd:        0000000000000000
  219. ShdPnd:        0000000000000000
  220. SigBlk:        0000000000010000
  221. SigIgn:        0000000000000006
  222. SigCgt:        0000000080000000
  223. CapInh:        0000000000000000
  224. CapPrm:        0000000000000000
  225. CapEff:        0000000000000000
  226. child pthread start
  227. =========/bin/cat /proc/27332/status=========
  228. Name:        a.out
  229. State:        S (sleeping)
  230. Tgid:        27332
  231. Pid:        27332
  232. PPid:        27260
  233. TracerPid:        0
  234. Uid:        547        547        547        547
  235. Gid:        507        507        507        507
  236. FDSize:        64
  237. Groups:        507
  238. VmSize:           13120 kB
  239. VmLck:               0 kB
  240. VmRSS:            4136 kB
  241. VmData:            3360 kB
  242. VmStk:             804 kB
  243. VmExe:               8 kB
  244. VmLib:            3760 kB
  245. SigPnd:        0000000000000000
  246. ShdPnd:        0000000000000000
  247. SigBlk:        0000000000000000
  248. SigIgn:        0000000000000006
  249. SigCgt:        0000000080000000
  250. CapInh:        0000000000000000
  251. CapPrm:        0000000000000000
  252. CapEff:        0000000000000000
  253. child end
  254. ~myTest() is called
  255. child exit good
  256. 4
  257. =========/bin/cat /proc/27332/status=========
  258. Name:        a.out
  259. State:        S (sleeping)
  260. Tgid:        27332
  261. Pid:        27332
  262. PPid:        27260
  263. TracerPid:        0
  264. Uid:        547        547        547        547
  265. Gid:        507        507        507        507
  266. FDSize:        64
  267. Groups:        507
  268. VmSize:           10040 kB
  269. VmLck:               0 kB
  270. VmRSS:            1056 kB
  271. VmData:             280 kB
  272. VmStk:             804 kB
  273. VmExe:               8 kB
  274. VmLib:            3760 kB
  275. SigPnd:        0000000000000000
  276. ShdPnd:        0000000000000000
  277. SigBlk:        0000000000010000
  278. SigIgn:        0000000000000006
  279. SigCgt:        0000000080000000
  280. CapInh:        0000000000000000
  281. CapPrm:        0000000000000000
  282. CapEff:        0000000000000000
  283. child pthread start
  284. =========/bin/cat /proc/27332/status=========
  285. Name:        a.out
  286. State:        S (sleeping)
  287. Tgid:        27332
  288. Pid:        27332
  289. PPid:        27260
  290. TracerPid:        0
  291. Uid:        547        547        547        547
  292. Gid:        507        507        507        507
  293. FDSize:        64
  294. Groups:        507
  295. VmSize:           13120 kB
  296. VmLck:               0 kB
  297. VmRSS:            4136 kB
  298. VmData:            3360 kB
  299. VmStk:             804 kB
  300. VmExe:               8 kB
  301. VmLib:            3760 kB
  302. SigPnd:        0000000000000000
  303. ShdPnd:        0000000000000000
  304. SigBlk:        0000000000000000
  305. SigIgn:        0000000000000006
  306. SigCgt:        0000000080000000
  307. CapInh:        0000000000000000
  308. CapPrm:        0000000000000000
  309. CapEff:        0000000000000000
  310. child end
  311. ~myTest() is called
  312. child exit good
  313. waiting ...
  314. =========/bin/cat /proc/27332/status=========
  315. Name:        a.out
  316. State:        S (sleeping)
  317. Tgid:        27332
  318. Pid:        27332
  319. PPid:        27260
  320. TracerPid:        0
  321. Uid:        547        547        547        547
  322. Gid:        507        507        507        507
  323. FDSize:        64
  324. Groups:        507
  325. VmSize:           10040 kB
  326. VmLck:               0 kB
  327. VmRSS:            1056 kB
  328. VmData:             280 kB
  329. VmStk:             804 kB
  330. VmExe:               8 kB
  331. VmLib:            3760 kB
  332. SigPnd:        0000000000000000
  333. ShdPnd:        0000000000000000
  334. SigBlk:        0000000000010000
  335. SigIgn:        0000000000000006
  336. SigCgt:        0000000080000000
  337. CapInh:        0000000000000000
  338. CapPrm:        0000000000000000
  339. CapEff:        0000000000000000
  340. exit....
复制代码


数据显示, gcc调用了析构函数 ( pthread_exit(NULL)退出线程 )

LZ 能否贴一下你的测试数据. 因我没有RedHat 9, gcc 3.2.2
作者: sevendays    时间: 2005-12-22 13:05
标题: 回复 20楼 Alligator27 的帖子
#uname -a
Linux CPCI 2.4.20-8 #1 Thu Mar 13 17:54:28 EST 2003 i686 i686 i386 GNU/Linux

#g++ -v
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)

gcc 是安装系统的时候系统装上的

LZ把你的gcc configure参数贴出来,我看看是不是参数上有出入?昨天查了一天的gcc.gnu.org,没有看出个名堂来


下面是我的结果,myTest::myTest()中分配的1M内存每次都没有释放,可能跟gcc有关
=================================================================
pragram started....
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            2288 kB
VmLck:               0 kB
VmRSS:             788 kB
VmData:              48 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
0
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            2288 kB
VmLck:               0 kB
VmRSS:             828 kB
VmData:              48 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child pthread start
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        S (sleeping)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            5372 kB
VmLck:               0 kB
VmRSS:            3940 kB
VmData:            3132 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000000000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child end
child exit good
1
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            3320 kB
VmLck:               0 kB
VmRSS:            1896 kB
VmData:            1080 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child pthread start
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            6400 kB
VmLck:               0 kB
VmRSS:            4976 kB
VmData:            4160 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000000000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child end
child exit good
2
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            4348 kB
VmLck:               0 kB
VmRSS:            2924 kB
VmData:            2108 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child pthread start
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        S (sleeping)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            7428 kB
VmLck:               0 kB
VmRSS:            6004 kB
VmData:            5188 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000000000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child end
child exit good
3
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            5376 kB
VmLck:               0 kB
VmRSS:            3952 kB
VmData:            3136 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child pthread start
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            8456 kB
VmLck:               0 kB
VmRSS:            7032 kB
VmData:            6216 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000000000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child end
child exit good
4
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            6404 kB
VmLck:               0 kB
VmRSS:            4980 kB
VmData:            4164 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child pthread start
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        S (sleeping)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            9484 kB
VmLck:               0 kB
VmRSS:            8060 kB
VmData:            7244 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000000000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child end
child exit good
waiting ...
=========/bin/cat /proc/576/status=========
Name:        pthreadtest2.ex
State:        S (sleeping)
Tgid:        576
Pid:        576
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            7432 kB
VmLck:               0 kB
VmRSS:            6008 kB
VmData:            5192 kB
VmStk:              12 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
exit....
作者: sevendays    时间: 2005-12-22 13:19
标题: 回复 21楼 sevendays 的帖子
昨天我在自己机器上装了个redhat 9.0 + gcc 3.3.2,测试结果基本跟这个一样,gcc的configure参数跟上面的一样,LZ把你的gcc configure参数贴出来,我再重装3.3.2试试看.

上贴是调用pthread_exit(NULL)的
注释pthread_exit(NULL) 行,打开return NULL 的结果如下:
================================
pragram started....
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            2284 kB
VmLck:               0 kB
VmRSS:             788 kB
VmData:              48 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
0
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            2284 kB
VmLck:               0 kB
VmRSS:             828 kB
VmData:              48 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child pthread start
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            5368 kB
VmLck:               0 kB
VmRSS:            3940 kB
VmData:            3132 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000000000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child end
~myTest() is called
child exit good
1
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            2288 kB
VmLck:               0 kB
VmRSS:             868 kB
VmData:              52 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child pthread start
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        S (sleeping)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            5368 kB
VmLck:               0 kB
VmRSS:            3948 kB
VmData:            3132 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000000000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child end
~myTest() is called
child exit good
2
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            2288 kB
VmLck:               0 kB
VmRSS:             868 kB
VmData:              52 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child pthread start
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            5368 kB
VmLck:               0 kB
VmRSS:            3948 kB
VmData:            3132 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000000000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child end
~myTest() is called
child exit good
3
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            2288 kB
VmLck:               0 kB
VmRSS:             868 kB
VmData:              52 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child pthread start
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        S (sleeping)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            5368 kB
VmLck:               0 kB
VmRSS:            3948 kB
VmData:            3132 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000000000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child end
~myTest() is called
child exit good
4
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            2288 kB
VmLck:               0 kB
VmRSS:             868 kB
VmData:              52 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child pthread start
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        S (sleeping)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            5368 kB
VmLck:               0 kB
VmRSS:            3948 kB
VmData:            3132 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000000000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
child end
~myTest() is called
child exit good
waiting ...
=========/bin/cat /proc/641/status=========
Name:        pthreadtest2.ex
State:        R (running)
Tgid:        641
Pid:        641
PPid:        434
TracerPid:        0
Uid:        500        500        500        500
Gid:        500        500        500        500
FDSize:        256
Groups:        500
VmSize:            2288 kB
VmLck:               0 kB
VmRSS:             868 kB
VmData:              52 kB
VmStk:               8 kB
VmExe:               8 kB
VmLib:            2168 kB
SigPnd:        0000000000000000
SigBlk:        0000000000010000
SigIgn:        8000000000000006
SigCgt:        0000000080000000
CapInh:        0000000000000000
CapPrm:        0000000000000000
CapEff:        0000000000000000
exit....
作者: Alligator27    时间: 2005-12-22 21:39
我的gcc configure如下:


  1. Reading specs from /usr/lib/gcc-lib/x86_64-redhat-linux/3.2.3/specs
  2. Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=x86_64-redhat-linux
  3. Thread model: posix
  4. gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-52)
复制代码


你的结果确实是pthread_exit()下, ~myTest() 没有调用. 那就是g++的bug了. 我不太明白为什么会这样. 你说你用gcc3.2.3也试过, 还是不对.

如果你都用return来结束线程, 程序还有内存泄漏吗?
作者: sevendays    时间: 2005-12-23 09:07
标题: 回复 23楼 Alligator27 的帖子
如果用return,目前这个程序就没有明显的内存泄漏;我还让我的一个同学帮忙测过,他的环境差不多,结果跟我的差不多。呵呵,先放放,现在钻在这里面不一定能真正找到原因,说不定哪天突然从看别的资料有新的启发呢!谢谢你啊 :) 别人都被我气跑了,就你比较实事求是,一起来测试这个东东,呵呵,为什么这里面就有那么多先入为主的人,不看明白我到底想干嘛呢。既然你那儿测试没问题,我就至少有一个收获:这个程序大问题应该不会有,谢谢啦:)
作者: sevendays    时间: 2005-12-23 09:11
标题: 回复 23楼 Alligator27 的帖子
我在我自己机器上装了个redhat9.0,然后升级了gcc为3.3.2版本,升级之前是3.2.2
作者: Alligator27    时间: 2005-12-23 09:59
不用谢, 我们不是讨论得很好吗.
我有个问题, 我的机器用的是NPTL. 不知道你是否一样.
作者: 俊狼    时间: 2005-12-23 12:18
受教
作者: sevendays    时间: 2005-12-23 13:02
标题: 回复 25楼 sevendays 的帖子
谢谢表示对你人品的尊重啊:)
一直没注意,提醒的好啊,我用的是LinuxThreads,这个好像不如redhat的NPTL吧?呵呵,我的redhat版本是不是太低了
扬沙洲的linux posix线程编程指南中说到:
============================
linuxthreads
管理线程容易成为瓶颈,这是这种结构的通病;同时,管理线程又负责用户线程的清理工作,因此,尽管管理线程已经屏蔽了大部分的信号,但一旦管理线程死亡,用户线程就不得不手工清理了,而且用户线程并不知道管理线程的状态,之后的线程创建等请求将无人处理。
=============另外介绍了NPTL
在技术实现上,NPTL仍然采用1:1的线程模型,并配合glibc和最新的Linux Kernel2.5.x开发版在信号处理、线程同步、存储管理等多方面进行了优化。和LinuxThreads不同,NPTL没有使用管理线程,核心线程的管理直接放在核内进行,这也带了性能的优化。

我系统的内核版本是2.4.20-8.....
看来又可能是线程库对pthread_exit(NULL)的实现问题了
作者: Alligator27    时间: 2005-12-23 23:20
确是跟线程的实现有关系. 我想g++会在unwind代码中生成~myTest()调用. pthread_exit()函数执行时没有与之协调, 从而没有调用到~myTest().

下面是g++在我的机器上生成的sendMsgs()汇编代码了.



  1. .globl _Z8sendMsgsPv
  2. .type _Z8sendMsgsPv,@function
  3. _Z8sendMsgsPv:
  4. .LFB1703:
  5. pushq %rbp
  6. .LCFI5:
  7. movq %rsp, %rbp
  8. .LCFI6:
  9. pushq %rbx
  10. .LCFI7:
  11. subq $1048632, %rsp
  12. .LCFI8:
  13. movq %rdi, -24(%rbp)
  14. movl $.LC3, %esi
  15. movl $_ZSt4cout, %edi
  16. .LEHB0:
  17. call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
  18. movq %rax, %rdi
  19. movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi
  20. call _ZNSolsEPFRSoS_E
  21. leaq -48(%rbp), %rdi
  22. call _ZN6myTestC1Ev
  23. .LEHE0:
  24. leaq -1048624(%rbp), %rdi
  25. movl $1048576, %edx
  26. movl $0, %esi
  27. call memset
  28. leaq -1048624(%rbp), %rdi
  29. movl $1048575, %edx
  30. movl $97, %esi
  31. call memset
  32. .LEHB1:
  33. call _Z11writeStatusv
  34. movl $.LC4, %esi
  35. movl $_ZSt4cout, %edi
  36. call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
  37. movq %rax, %rdi
  38. movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi
  39. call _ZNSolsEPFRSoS_E
  40. movl $0, %edi
  41. call pthread_exit
  42. .LEHE1:
  43. .L9:
  44. movq %rax, -1048632(%rbp)
  45. movq -1048632(%rbp), %rbx
  46. leaq -48(%rbp), %rdi
  47. call _ZN6myTestD1Ev
  48. movq %rbx, -1048632(%rbp)
  49. movq -1048632(%rbp), %rdi
  50. .LEHB2:
  51. call _Unwind_Resume
  52. .LEHE2:
  53. .LFE1703:
  54. .Lfe3:
  55. .size _Z8sendMsgsPv,.Lfe3-_Z8sendMsgsPv
  56. .section .gcc_except_table,"a",@progbits
复制代码


我google了一下, 有人说绝对不要用pthread_exit(), 用return. 就是因为某些系统会有类似你的问提.

[ 本帖最后由 Alligator27 于 2005-12-23 23:22 编辑 ]
作者: sevendays    时间: 2005-12-27 13:14
标题: 回复 29楼 Alligator27 的帖子
呵呵,谢谢:)




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2