多线程退出的方案问题。

不要做咸鱼 2013-01-22 05:52:50
还是更新模块问题,采用服务器和客户端模式,服务器使用线程池来等待连接客户端的连入请求。
问题是我在创建线程的时候没有保存线程句柄,而且线程池中线程数是动态变化的即如果客户端多的话线程也多(但是不超过最大线程限制),服务器如果长时间没有客户端连接的话线程就会退出一部分,只留几个线程来等待连接。
问题是如果我想终止服务器的时候,那么多的线程直接就异常退出,肯定会有很多堆栈内存没有释放。想用waitformultyobjects 来解决但是句柄数组不好弄,而且传输文件时间很长用这种方法意义不大感觉。
有好的方案吗大神们?求解
(别说用iocp了,小弟现在正在学习ing...)
...全文
4005 39 点赞 打赏 收藏 举报
写回复
39 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
文俊2014 2013-02-01
引用 36 楼 sd530842780 的回复:
最终通过我和你们的努力解决了
咋解决的? 一起学习学习
  • 打赏
  • 举报
回复
不要做咸鱼 2013-01-30
引用 37 楼 tiantangxingkong 的回复:
引用 15 楼 sd530842780 的回复:引用 13 楼 zhao4zhong1 的回复:不要企图优雅的结束(因为这是不可能办到的) 而要在烂的不能再烂的摊子上也能重整河山! 这个烂摊子我是受够了 进程都退出了你还要怎么释放内存,要修改OS代码吗?
其实我原先的意思表达的不太正确,现在一想就是让进程结束前结束工作线程。
  • 打赏
  • 举报
回复
tiantangxingkong 2013-01-30
引用 15 楼 sd530842780 的回复:
引用 13 楼 zhao4zhong1 的回复:不要企图优雅的结束(因为这是不可能办到的) 而要在烂的不能再烂的摊子上也能重整河山! 这个烂摊子我是受够了
进程都退出了你还要怎么释放内存,要修改OS代码吗?
  • 打赏
  • 举报
回复
不要做咸鱼 2013-01-28
最终通过我和你们的努力解决了
  • 打赏
  • 举报
回复
wumn29 2013-01-28
引用 23 楼 zhao4zhong1 的回复:
引用 13 楼 zhao4zhong1 的回复:不要企图优雅的结束(因为这是不可能办到的) 而要在烂的不能再烂的摊子上也能重整河山! 这是一个哲学问题。 任何问题首先是一个哲学问题,不是吗? 参考《骇客帝国》
  • 打赏
  • 举报
回复
lcgkm 2013-01-28
线程池 程序退出时,主线程向所有子线程发送退出命令,并等待全部子线程退出。 之后主线程退出,线程池销毁。 咱这只有linux的代码,lz需要,咱再发上来吧。
  • 打赏
  • 举报
回复
yujie_v 2013-01-25
引用 29 楼 yujie_v 的回复:
自己加个判断,句柄还是要保存的,或者发个标志位,让线程自动退出。
全局变量或者使用参数传递过去。。。
  • 打赏
  • 举报
回复
Coder_Yuan 2013-01-25
避免内存泄露的方法是线程自己退出,可以在线程里面的适当位置判断退出条件,最好不要用事件或者内核对象的方式,如果用事件的话会出现下面情况:调用一个函数正好开始就分配了512byte内存,这个时候你的事件来了那你就停了这个线程,那就没有机会调用删除512byte内存的函数
  • 打赏
  • 举报
回复
赵4老师 2013-01-25
引用 28 楼 sd530842780 的回复:
引用 27 楼 Oringe_new 的回复:既然终止了 还管那些内存干嘛? 虽然这样扔给系统处理有点不负责任 但是既然有简单的方法 还要把逻辑设计得这么复杂干嘛 现在需要了,有新的需求,在不退出程序的情况下终止线程然后重新运行。
“在不退出程序的情况下终止线程然后重新运行” 比不上 “退出程序再进入程序时能接退出前继续干活”
  • 打赏
  • 举报
回复
不要做咸鱼 2013-01-25
引用 29 楼 yujie_v 的回复:
自己加个判断,句柄还是要保存的,或者发个标志位,让线程自动退出。
这个标志位怎么发呢?要保存链表?
  • 打赏
  • 举报
回复
yujie_v 2013-01-25
自己加个判断,句柄还是要保存的,或者发个标志位,让线程自动退出。
  • 打赏
  • 举报
回复
不要做咸鱼 2013-01-25
引用 27 楼 Oringe_new 的回复:
既然终止了 还管那些内存干嘛? 虽然这样扔给系统处理有点不负责任 但是既然有简单的方法 还要把逻辑设计得这么复杂干嘛
现在需要了,有新的需求,在不退出程序的情况下终止线程然后重新运行。
  • 打赏
  • 举报
回复
不要做咸鱼 2013-01-24
引用 25 楼 nanjingjiangbiao 的回复:
可以考虑外面包装一个线程池,线程池推出的时候,发出通信量给各个子线程
看来只能这样了。我现在就是做一个管理线程,由这个管理线程来管理那些工作线程 总的来说就是主线程———wait———>管理线程-----wait多个----->工作线程;
  • 打赏
  • 举报
回复
改bug神枪手 2013-01-24
可以考虑外面包装一个线程池,线程池推出的时候,发出通信量给各个子线程
  • 打赏
  • 举报
回复
Orange_ou 2013-01-24
既然终止了 还管那些内存干嘛? 虽然这样扔给系统处理有点不负责任 但是既然有简单的方法 还要把逻辑设计得这么复杂干嘛
  • 打赏
  • 举报
回复
lin5161678 2013-01-23
引用计数? 非0等待退出 0 正常退出
  • 打赏
  • 举报
回复
sowhat_Ah 2013-01-23
引用 10 楼 zilaishuichina 的回复:
你这个需求 顺序应该是 线程池的子线程结束->线程池结束->主线程结束程序退出 有一个g_Exit,为true表示主线程想退出了 然后创建Event g_hThreadPoolExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); WaitForSingleObject(g_hThreadPoolExitEvent……
WaitForSingleObject也可以直接等待线程句柄,不需要用CreateEvent(),SetEvent()吧! WaitForSingleObject与WaitForMultipleObjects应该可以等待几乎所有window内核对象; CreateEvent()返回的也是一个Handle,CreateThread()返回的也是一个Handle,都是window的内核对象。
  • 打赏
  • 举报
回复
zilaishuichina 2013-01-23
你这个需求 顺序应该是 线程池的子线程结束->线程池结束->主线程结束程序退出 有一个g_Exit,为true表示主线程想退出了 然后创建Event g_hThreadPoolExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); WaitForSingleObject(g_hThreadPoolExitEvent, INFINITE); 对于非阻塞的模型 线程池创建的线程应该是 while(!g_Exit) { //do something; sleep(1); } 然后线程池在所有线程退出之后 就是检测到线程个数为0的时候 SetEvent(g_hThreadPoolExitEvent); 如果你是阻塞模型 那就直接强退吧
  • 打赏
  • 举报
回复
sowhat_Ah 2013-01-23
windows下当然用WaitForMultipleObjects或者WaitForSingleObject最方便快捷,句柄数组不好用,可以用句柄容器啊,C++的容器也是支持HANDLE这种类型的。 试试下面的代码?

        //句柄丢进容器
        hthreads.push_back(CreateThread(NULL,0,ModuThread,NULL,0,&t_id));

        //等待结束
	std::vector<HANDLE>::iterator it_hthr = hthreads.begin();
	while (it_hthr != hthreads.end())
	{
		if (WaitForSingleObject((*it_hthr),INFINITE)!=WAIT_OBJECT_0)
		{
			std::cout<<"线程未正确结束"<<std::endl;
			_ptracelog->error("线程未正确结束");
		}
		CloseHandle((*it_hthr));
		it_hthr++;
	}
  • 打赏
  • 举报
回复
Joseph_ 2013-01-23
线程库里面不是有2个函数 可以在线程异常退去之后 释放你写在这2个函数之间那份代码所获取的资源吗》? 我是做linux 开发的 这个下面我知道那2个函数是: pthread_cleanup_push() /* 如果线程异常退去会释放此处获取的资源。 */ pthread_cleanup_pop();
  • 打赏
  • 举报
回复
加载更多回复
相关推荐
发帖
C++ 语言
加入

6.0w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
申请成为版主
帖子事件
创建了帖子
2013-01-22 05:52
社区公告
暂无公告