免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 21013 | 回复: 44
打印 上一主题 下一主题

加急跪求帮助:线程资源释放的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-21 19:28 |只看该作者 |倒序浏览
5可用积分
小妹这两周遇到一个可能要丢饭碗的问题,已经折磨我2周了,再不能解决我就要~555了,危难时刻想恳请各位哥哥、姐姐、弟弟妹妹帮个忙,心急如焚,拜谢!

问题描述:要实现一个网络服务端程序负责实时监测各个与之连接/断开的网络客户端的数据收发。
    我的socket服务端程序中需要实时监测客户连接,每发现一个新的客户连接我就创建一个MySockClient类的对象:MySockClient

类对象启动时会pthread_create一个线程去负责与对应客户端通信(这个线程是个while(1)的死循环,不会主动退出),当客户端断

开时程序会delete MySockClient类对象。现在程序整体已经实现完毕,但已经测试发现,当客户端反复连接/断开时,

pthread_create每执行一次时就会消耗掉大量的内存,在delete MySockClient类对象时并没有随之释放,导致最后资源耗尽而崩溃。

注:MySockClient类处理中没有动态开辟的内存资源,此处损耗经确定为线程创建所产生
我把程序大致意思再用一个简略的框架程序描述如下:


class MySockClient
{
protected :
        pthread_t FHandle;
        bool TGC_CreateThread();
               
public :
        MySockClient(bool bCreateThread)
        {
            ....
            int ret;
            ret = pthread_create(&FHandle,NULL,TGC_ThreadFunc,(void *)this);
            if ( ret !=0 )
                printf ("Create pthread error!\n");
                return;
               }

            ....
        }       
        ~MySockClient()
        {
            ....
                pthread_kill(FHandle, 0);
            ....
        };
        ....
};
//上面的线程处理函数TGC_ThreadFunc是一个包含while(1)的监测处理程序,只有当类delete时才能退出循环

在主进程中,服务端程序将不断监测客户连接情况,当新来客户连接时将new一个MySockClient的对象(其实也是创建一个线程为其处理事物),当发现这个客户断开连接时

会调用delete MySockClient 以释放类的资源, 其中主进程不会退出


现在的问题是:每次我new一个MySockClient的对象时,执行pthread_create()将消耗大量的资源,但delete MySockClient时程序

调用了pthread_kill(FHandle, 0)却没有把线程的资源释放掉。问题到底出在哪个地方,并且怎么解决呢?



小妹跪求各位指点,谢谢,谢谢!

最佳答案

查看完整内容

不想顺着楼主的想法去想怎么做,我觉得你的起初的思路有问题,即使有人帮你解决了这个问题,估计你的饭碗会丢得很快了 ================================为什么不改一下你的设计,我以前做过跟你这个很相似的一个程序,凭经验提点意见:首先,最好不要动态创建线程来完成任务,这样实现起来麻烦,而且现在你已经让申请资源和回收资源搞得很烦了。其次,为什么不一开始就创建200或者500个线程,闲着,如果有连接到来,就将 ...

论坛徽章:
0
2 [报告]
发表于 2008-08-21 19:28 |只看该作者
不想顺着楼主的想法去想怎么做,我觉得你的起初的思路有问题,即使有人帮你解决了这个问题,估计你的饭碗会丢得很快了
================================
为什么不改一下你的设计,我以前做过跟你这个很相似的一个程序,凭经验提点意见:

首先,最好不要动态创建线程来完成任务,这样实现起来麻烦,而且现在你已经让申请资源和回收资源搞得很烦了。

其次,为什么不一开始就创建200或者500个线程,闲着,如果有连接到来,就将该任务分配给一个空闲线程,或者加入到正在工作的线程的任务队列中,如果不幸500个线程都忙了,而且他们的
任务队列都满了,你可以告诉你的老板,这就是你的程序的性能极限

[ 本帖最后由 duanjigang 于 2008-8-21 21:20 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2008-08-21 19:58 |只看该作者
设置一个标识位flag, 初始为0, 在析构函数中去掉pthread_kill, 然后加上flag = 1;表示该对象已经销毁.
另外,在TGC_ThreadFunc中, 不是一个无限循环么? 在循环之初, 判断flag的值, 如果为1, 则调用pthread_exit()退出线程.

论坛徽章:
0
4 [报告]
发表于 2008-08-21 20:00 |只看该作者
>>每次我new一个MySockClient的对象时,执行pthread_create()将消耗大量的资源
线程创建不会消耗很大的资源啊.

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
5 [报告]
发表于 2008-08-21 20:15 |只看该作者
原帖由 zydzmapx 于 2008-8-21 19:28 发表
现在的问题是:每次我new一个MySockClient的对象时,执行pthread_create()将消耗大量的资源,

有资源消耗情况的数据么?

论坛徽章:
0
6 [报告]
发表于 2008-08-21 20:16 |只看该作者
其实真的的原因是你没有认真看pthread_kill的说明:
if sig is zero, error checking shall be performed but  no
       signal shall actually be sent.

所以此时你只是在检查你的线程是否存在 ,但是并没有终止这个线程.

或者你直接使用pthread_cancel()取代pthread_kill()

[ 本帖最后由 scutan 于 2008-8-21 20:25 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2008-08-21 20:36 |只看该作者
发信号0首先没有用,发起他信号的话也可能会对整个进程造成影响,
建立看看这组函数
pthread_cancel()
pthread_setcancelstate()
pthread_setcanceltype()

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
8 [报告]
发表于 2008-08-21 21:04 |只看该作者
原帖由 scutan 于 2008-8-21 20:16 发表
其实真的的原因是你没有认真看pthread_kill的说明:

所以此时你只是在检查你的线程是否存在 ,但是并没有终止这个线程.

或者你直接使用pthread_cancel()取代pthread_kill()


     5楼已经指出楼主用法的关键问题,使用pthread_kill(tid, 0)无法取消线程,即使第二个参数传入正确的信号值,也会带来额外的复杂性,比如进程级信号action和各线程信号mark设置不当都会带来问题。用pthtead_cacel(tid)更合适。
    还有补充的是,记得使用pthread_detach或pthread_join或设置线程属性detachstate,否则线程终止后,资源也不能释放。

论坛徽章:
0
9 [报告]
发表于 2008-08-21 22:18 |只看该作者

回复 #2 scutan 的帖子

类似您说的flag标志在while循环中已经存在,在delete类对象时程序已经经过~MySockClient()这部分,所以只要能执行线程关闭的方法就可以了,但我的pthread_kill(FHandle, 0)感觉没起任何用处

论坛徽章:
0
10 [报告]
发表于 2008-08-21 22:21 |只看该作者
回3楼:

根据我的反复测试,可以确定每执行一次pthread_create()将消耗几K或几十K的资源,正是由于此,才存在要释放线程资源的问题
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP