请问怎样在服务器程序退出前结束监听线程?

时间:2022-11-17 22:40:05
想在服务器程序退出前结束所有的线程,以释放资源,避免内存泄漏。在while()语句中设置了退出条件,但是由于在监听线程中ACCEPT()是一直阻塞的,故开启线程后再改变该条件根本不起作用。只有在主线程退出时该监听线程才会退出,造成了内存泄漏。怎样解决这个问题呢?可能有许多地方说的不清楚,还是希望大家能够帮忙想一想。谢谢

31 个解决方案

#1


一般说来这样的程序用客户端发消息让其退出比较好
连接之后发送一个代号,决定进行的操作,如果是退出消息服务器退出即可

#2


在while()退出后,结束这个线程

#3


我猜你一定是socket编程,ACCEPT是接受连接请求。如果是这样,你可以在主程序中用CloseSocket关闭监听socket句柄,这样ACCEPT就会返回错误,你检测到错误后就可以主动退出当前线程。

#4


tanzs(tanzs)说的对 这个方法可行

#5


对呀,我用的是socket编程。而我如果在主线程中用CloseSocket关闭监听套接字时,程序运行到此处就死了,没有任何响应。我想这是因为监听socket在使用的原因。这样的话该怎么处理呢?

#6


你可以在调试状态运行跟踪出错的原因,还有你检查了每一个socket调用的返回值了吗?

#7


gz,
刚写过一个网络的,不过用的是MFC里面的类,响应了OnAccept,所以没这个问题,
但是MFC在底层估计也是开线程来接受请求的,不知道他是怎么实现的

#8


我是在debug下运行的。利用断点跟踪,在关闭监听套接字这一行,出现下面的提示:
(call stack unavailable while child is running)。
我想这一个child is running 指的就是accept()函数在等待用户连接,一直阻塞在那儿,因为我在accept()函数后加的TRACE语句没有显示出来。还有“每一个socket调用的返回值”指的是什么?所有调用了socket的函数的返回值吗?还是socket本身的句柄?

#9


服务器程序关闭的第一步
首先closesocket服务器的监听socket
这样你的监听线程中的accept就会返回,这是你在判断退出条件,然后退出,清理内存,资源

#10


S_W_A_T(冰龙) 
服务器程序关闭的第一步
首先closesocket服务器的监听socket
这样你的监听线程中的accept就会返回,这是你在判断退出条件,然后退出,清理内存,资源

我原来也是这样想的,可是当程序运行到closesocket(监听套接字)时程序就没反应了,可见accept()也根本就没有退出,无法继续进行条件的判断,根本退不出来呀。怎么办?

#11


我原来也是这样想的,可是当程序运行到closesocket(监听套接字)时程序就没反应了,可见accept()也根本就没有退出,无法继续进行条件的判断,根本退不出来呀。怎么办?


不可能
你先shutdown试试

#12


可是当程序运行到closesocket(监听套接字)时程序就没反应了,可见accept()也根本就没有退出

你看看msdn上面写的很清楚,肯定会返回的,如果有错的话你看看你的其他部分,我刚刚实现一遍
你要不在程序中加个消息框,看看到底退出了没有

#13


行,我再试试看。先谢谢了,呵呵

#14


nRet=closesocket(g_lstnStuSkt);利用断点检测(或WSAGetLastError()):nRet=-858993460 
怎么会出现负值呢?这是什么错误?

#15


呵呵,这个负值是声明nRet时的初始值,没什么关系。出现这个值说明closesocket()并没有返回值。不知道是不是vc的原因,我没怎么改,只是又多试了几次,closesocket的返回值就变成0了,说明closesocket的处理没有什么错误。可是再往下就运行不了了,监听线程也没有退出

#16


不清楚了,我的可以
不行的话,你就TerminateThread(),关闭监听线程

#17


先杀杀毒吧:P
不过也许是程序中其他原因造成的,建议你用排除法或累加法...

#18


昨天网络断了,没能上网。昨天我弄错了一个地方:我把closesocket的返回值给看错了,是关闭的另一个套接字的返回值,而不是监听套接字的。关闭监听套接字时closesocket函数并没有返回值,显示的nRet还是刚开始分配时的随机值。
我刚刚又试了两种情况,一个把accept()函数给屏蔽掉了,一个使用accept()等待连接.结果显示没有被accept函数调用的那个套接字可以正常关闭,由于该套接字被关闭后已不再是套接字,listen函数检测到错误10038后退出.而另一个正在被accept函数调用的套接字则无法关闭。我觉得这正好说明了是accept函数阻塞的原因,应该没有错吧?这样的话该怎么处理呢?

#19


有谁知道该怎么处理吗?

#20


难道你是先accept后listen的吗?

#21


不是,先监听后accept,要不我把测试的程序发一份帮我瞧瞧?

#22


我的邮箱是tanzs0@163.net

#23


按照我的方法你试成功了吗?

#24


three steps to close a socket communication.
good article in CodeGuru.com

#25


还是不行。不过我觉得socket和wsasocket这两个应该都可以的呀!

#26


哦,可能我原来有地方没改好,现在按照你的方法又试了一下,是可以退出的。不过我不明白socket和WSASocket有什么区别呢,为什么一个可以正常关闭而另一个就不可以了呢?

#27


^_^,thanks!

#28


关注...

#29


呵呵,昨天连着回了3次才发觉不能再继续回了!今天再重写一下;是不是用accept函数进行接收时其所使用的套接字要用socket产生,而用WSAAccept函数进行接收时所使用的套接字要用WSASocket产生呀?只是不太清楚用WSAAccept时后两个参数该怎样写.
不管怎么样,问题现在解决了,真的很谢谢大家,特别是tanzs.

#30


我想可能是因为socket函数创建的句柄缺省为“overlap”模式吧。这是socket和WSASocket的一个区别。你可以看看MSDN中的解释。

#31


恩,好的。该帖可以结了。谢谢!

#1


一般说来这样的程序用客户端发消息让其退出比较好
连接之后发送一个代号,决定进行的操作,如果是退出消息服务器退出即可

#2


在while()退出后,结束这个线程

#3


我猜你一定是socket编程,ACCEPT是接受连接请求。如果是这样,你可以在主程序中用CloseSocket关闭监听socket句柄,这样ACCEPT就会返回错误,你检测到错误后就可以主动退出当前线程。

#4


tanzs(tanzs)说的对 这个方法可行

#5


对呀,我用的是socket编程。而我如果在主线程中用CloseSocket关闭监听套接字时,程序运行到此处就死了,没有任何响应。我想这是因为监听socket在使用的原因。这样的话该怎么处理呢?

#6


你可以在调试状态运行跟踪出错的原因,还有你检查了每一个socket调用的返回值了吗?

#7


gz,
刚写过一个网络的,不过用的是MFC里面的类,响应了OnAccept,所以没这个问题,
但是MFC在底层估计也是开线程来接受请求的,不知道他是怎么实现的

#8


我是在debug下运行的。利用断点跟踪,在关闭监听套接字这一行,出现下面的提示:
(call stack unavailable while child is running)。
我想这一个child is running 指的就是accept()函数在等待用户连接,一直阻塞在那儿,因为我在accept()函数后加的TRACE语句没有显示出来。还有“每一个socket调用的返回值”指的是什么?所有调用了socket的函数的返回值吗?还是socket本身的句柄?

#9


服务器程序关闭的第一步
首先closesocket服务器的监听socket
这样你的监听线程中的accept就会返回,这是你在判断退出条件,然后退出,清理内存,资源

#10


S_W_A_T(冰龙) 
服务器程序关闭的第一步
首先closesocket服务器的监听socket
这样你的监听线程中的accept就会返回,这是你在判断退出条件,然后退出,清理内存,资源

我原来也是这样想的,可是当程序运行到closesocket(监听套接字)时程序就没反应了,可见accept()也根本就没有退出,无法继续进行条件的判断,根本退不出来呀。怎么办?

#11


我原来也是这样想的,可是当程序运行到closesocket(监听套接字)时程序就没反应了,可见accept()也根本就没有退出,无法继续进行条件的判断,根本退不出来呀。怎么办?


不可能
你先shutdown试试

#12


可是当程序运行到closesocket(监听套接字)时程序就没反应了,可见accept()也根本就没有退出

你看看msdn上面写的很清楚,肯定会返回的,如果有错的话你看看你的其他部分,我刚刚实现一遍
你要不在程序中加个消息框,看看到底退出了没有

#13


行,我再试试看。先谢谢了,呵呵

#14


nRet=closesocket(g_lstnStuSkt);利用断点检测(或WSAGetLastError()):nRet=-858993460 
怎么会出现负值呢?这是什么错误?

#15


呵呵,这个负值是声明nRet时的初始值,没什么关系。出现这个值说明closesocket()并没有返回值。不知道是不是vc的原因,我没怎么改,只是又多试了几次,closesocket的返回值就变成0了,说明closesocket的处理没有什么错误。可是再往下就运行不了了,监听线程也没有退出

#16


不清楚了,我的可以
不行的话,你就TerminateThread(),关闭监听线程

#17


先杀杀毒吧:P
不过也许是程序中其他原因造成的,建议你用排除法或累加法...

#18


昨天网络断了,没能上网。昨天我弄错了一个地方:我把closesocket的返回值给看错了,是关闭的另一个套接字的返回值,而不是监听套接字的。关闭监听套接字时closesocket函数并没有返回值,显示的nRet还是刚开始分配时的随机值。
我刚刚又试了两种情况,一个把accept()函数给屏蔽掉了,一个使用accept()等待连接.结果显示没有被accept函数调用的那个套接字可以正常关闭,由于该套接字被关闭后已不再是套接字,listen函数检测到错误10038后退出.而另一个正在被accept函数调用的套接字则无法关闭。我觉得这正好说明了是accept函数阻塞的原因,应该没有错吧?这样的话该怎么处理呢?

#19


有谁知道该怎么处理吗?

#20


难道你是先accept后listen的吗?

#21


不是,先监听后accept,要不我把测试的程序发一份帮我瞧瞧?

#22


我的邮箱是tanzs0@163.net

#23


按照我的方法你试成功了吗?

#24


three steps to close a socket communication.
good article in CodeGuru.com

#25


还是不行。不过我觉得socket和wsasocket这两个应该都可以的呀!

#26


哦,可能我原来有地方没改好,现在按照你的方法又试了一下,是可以退出的。不过我不明白socket和WSASocket有什么区别呢,为什么一个可以正常关闭而另一个就不可以了呢?

#27


^_^,thanks!

#28


关注...

#29


呵呵,昨天连着回了3次才发觉不能再继续回了!今天再重写一下;是不是用accept函数进行接收时其所使用的套接字要用socket产生,而用WSAAccept函数进行接收时所使用的套接字要用WSASocket产生呀?只是不太清楚用WSAAccept时后两个参数该怎样写.
不管怎么样,问题现在解决了,真的很谢谢大家,特别是tanzs.

#30


我想可能是因为socket函数创建的句柄缺省为“overlap”模式吧。这是socket和WSASocket的一个区别。你可以看看MSDN中的解释。

#31


恩,好的。该帖可以结了。谢谢!