none
请大侠帮我看一下,为什么程序会死(应该是线程不能退出) 就100来行代码,清晰易懂 RRS feed

  • 问题

  • 就100来行代码,可我找不出原因,能退出线程
    问题好几天都解决不了,真是没招了,以为会,可有错就是改不出
    ---------------------问题描述开始---------------------
    而是在正常运行状态下,对方突然断开,而我这又在不停地发消息时,出现的假死(发送失败,线程关闭不了)

    就是说,对方关闭后。我这在发送消息时,如果发现有错,就自动关闭此线程(丢失的消息不管)
    如果再一次发送,发现无线程,就再开线程,有线程就直接发送
    ---------------------问题描述结束---------------------
    源码见(完整程序,可调试)
    http://www.namipan.com/d/f68d60317bdbdbd5e52fe4a3176aaceefa68f111f1280700

    也可从几天前的帖子看(CSDN)
    http://topic.csdn.net/u/20090518/14/c9c63c99-67f0-4069-a3dc-6abf40d0f8d6.html?seed=1341770964

    主要代码如下:
    C/C++ code
    int OpenSocket(CString SendData) { if (m_hEvent) { WaitForSingleObject(m_hEvent,INFINITE); //操作变量前先等线程处理完毕 ResetEvent(m_hEvent); } SendDataBuf=SendData; DWORD AIExitCode; if(hThread)//看看线程 { GetExitCodeThread(hThread,&AIExitCode);//捕捉线程 if(Isreturn) { PostThreadMessage(ThreadID,WM_CLOSE,0,0); TerminateThread(hThread,0); CloseHandle(hThread); } Isreturn=false; if(AIExitCode==STILL_ACTIVE) { PostThreadMessage(ThreadID,WM_USERMSG,0,(LPARAM)&SendDataBuf); return 1; } CloseHandle(hThread); } else { m_hEvent=CreateEvent(NULL,TRUE,FALSE,"socketdll"); hThread = (HANDLE)_beginthreadex(NULL,0,NewThread,0,0,&ThreadID); if(hThread == 0) { CloseHandle(m_hEvent); return 0; } PostThreadMessage(ThreadID,WM_USERMSG,0,(LPARAM)&SendDataBuf); } return 1; } static unsigned WINAPI NewThread(void *arg) { if(StartEnv()) return 0; sockClient=socket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr=inet_addr(QSerAddress); addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(QSerPort); if(INVALID_SOCKET == connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))) { closesocket(sockClient); WSACleanup(); return 0; } int buflen = 0; setsockopt(sockClient,SOL_SOCKET,SO_SNDBUF,(const char*)&buflen,sizeof(buflen)); MSG msg; if(!SetEvent(m_hEvent))//set thread start event return 1; send(sockClient,SendDataBuf,strlen(SendDataBuf)+1,0); while (1) { if(GetMessage(&msg,0,0,0))//get msg from message queue { if (msg.message == WM_CLOSE) break; switch(msg.message) { case WM_USERMSG: CString *pStr = (CString*)msg.lParam; if(0 > send(sockClient,pStr->GetBuffer(0),pStr->GetLength()+1,0)) { Sleep(10); if(0 > send(sockClient,pStr->GetBuffer(0),pStr->GetLength()+1,0)) Isreturn=true; } pStr->ReleaseBuffer(); SetEvent(m_hEvent); break; } } } closesocket(sockClient); WSACleanup(); return 1; }
    2009年5月20日 6:49

答案

  • 不要把Send这种东西放到消息对列里特别是 Sleep();MSDN上有特别说明的,建立一个新的线程就不会卡死了.

    You have to be careful when using Sleep and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. If you have a thread that uses Sleep with infinite delay, the system will deadlock. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than Sleep.


    Hello world
    2009年5月21日 2:54
    版主
  • 谢谢楼上的热心解答。
    原因基本找到,真正的问题是WaitForSingleObject无限的等待
    • 已标记为答案 flyskytoday 2009年5月21日 10:07
    2009年5月21日 9:51

全部回复

  • 不要把Send这种东西放到消息对列里特别是 Sleep();MSDN上有特别说明的,建立一个新的线程就不会卡死了.

    You have to be careful when using Sleep and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. If you have a thread that uses Sleep with infinite delay, the system will deadlock. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than Sleep.


    Hello world
    2009年5月21日 2:54
    版主
  • 谢谢楼上的热心解答。
    原因基本找到,真正的问题是WaitForSingleObject无限的等待
    • 已标记为答案 flyskytoday 2009年5月21日 10:07
    2009年5月21日 9:51