Multithreading closesocket后服务器崩溃
我有一个多线程应用程序,它定期轮询几百个设备。 每个线程服务于一个设备,其套接字和其他描述符封装在单个对象中,因此没有共享描述符。 当我尝试将描述符fSock设置为0时,closesocket(fSock)之后偶尔会出现应用程序崩溃 我假设,如果closesocket(fSock)返回SOCKET\u错误,我不应该将fSock设置为0。 还是有其他原因 我的代码:Multithreading closesocket后服务器崩溃,multithreading,winsock,Multithreading,Winsock,我有一个多线程应用程序,它定期轮询几百个设备。 每个线程服务于一个设备,其套接字和其他描述符封装在单个对象中,因此没有共享描述符。 当我尝试将描述符fSock设置为0时,closesocket(fSock)之后偶尔会出现应用程序崩溃 我假设,如果closesocket(fSock)返回SOCKET\u错误,我不应该将fSock设置为0。 还是有其他原因 我的代码: bool _EthDev::Connect() { int sockErr, ret, i, j; int szOu
bool _EthDev::Connect()
{
int sockErr, ret, i, j;
int szOut = sizeof(sockaddr_in);
// create socket
if ((fSock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
sockErr = GetLastError();
Log("Invalid socket err %d", sockErr);
fSock = 0;
return false;
}
// set fast closing socket (by RST)
linger sLinger;
sLinger.l_onoff = 1;
sLinger.l_linger = 0;
if (sockErr = setsockopt(fSock, SOL_SOCKET, SO_LINGER, (const char FAR*)&sLinger, sizeof(linger)))
{
sockErr = WSAGetLastError();
Log("Setsockopt err %d", sockErr);
closesocket(fSock);
fSock = 0; // here crashes
return false;
}
// connect to device
fSockaddr.sin_port = htons((u_short)(baseport));
if (connect(fSock, (struct sockaddr*)&fSockaddr, szOut))
{
closesocket(fSock);
fSock = 0;
return false;
}
...
return true;
}
我有多线程应用程序。。。[它]偶尔会崩溃
偶尔崩溃的多线程应用程序是竞争条件的典型症状。我认为,为了防止崩溃,您需要找出代码中的竞争条件,并修复它
我假设,如果closesocket(fSock)返回,我不应该将fSock设置为0
套接字错误。还是有其他原因
我怀疑这个问题实际上与closesocket()或将fSock设置为0有关。请记住,套接字实际上只是整数,将整数设置为0本身不太可能导致崩溃。可能导致崩溃的是对无效内存的写入,fSock=0
会写入成员变量fSock
所在的内存位置
因此,一个更可能的假设是,线程线程A被线程B删除,而线程A仍然处于调用连接()的中间。这很可能在执行connect()调用时发生,因为阻塞connect()调用可能需要较长的时间才能返回。因此,如果有另一个线程在connect()调用期间粗暴地删除了_EthDev对象,那么一旦connect()返回,将写入(现在已删除的)_EthDev对象以前所在位置的下一行代码将是“fSock=0;”行,这可能会导致崩溃
我建议您检查删除_EthDev对象的代码,如果在删除_EthDev对象之前不小心先关闭使用这些对象的任何线程(并等待线程退出!),那么您应该重写它,以便它能够可靠地执行此操作。当另一个线程可能仍在使用某个对象时删除该对象是自找麻烦。0不是套接字的无效值。如果要指出fSock不再是有效套接字,则应将其设置为无效的\u套接字,而不是0,因为根据定义,无效的\u套接字是一个永远不会被有效套接字使用的值。谢谢Jeremy!实际上,我在应用程序启动时创建对象并启动线程,在退出之前停止线程并删除对象。但现在我认为问题更多的是多线程而不是套接字。