我在做socket的服务程序,我的思路是定义一个参数结构指针param,存放socket以及client的地址等信息。accept到一个连接后,m_param=new param,然后将socket以及client的地址等信息赋值给m_param,创建子线程,将m_param作参数传递。在子线程结束时,delete m_param。
现在的问题是:
多线程并发时,子线程执行到delete m_param;出错。
多线程串行或封掉delete m_param语句都不会出错。
问题在哪里呢?

解决方案 »

  1.   

    你的子线程用到的是同一个m_param?是不是你只对m_param分配了一次内存,然后再把这个当作参数传给所有的子线程?
      

  2.   

    源代码大致如下:typedef struct tagWORKPARAM
    {
    SOCKET sckClient;
    sockaddr_in addr;
    }WORKPARAM;Listen 线程:
    {
         int iRet, addrLen;
       sockaddr_in addr, addrAccept;
       SOCKET sckListen, sckAccept;
      char pszMsg[512]; sckListen = socket(AF_INET, SOCK_STREAM, 0);
    iRet = gethostname(pszMsg, 256);
    hostent* pEnt = gethostbyname(pszMsg);
        
    memcpy(&(addr.sin_addr), pEnt->h_addr, pEnt->h_length);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9000);

    iRet = bind(sckListen, (const sockaddr*)&addr, sizeof(addr));
    iRet = listen(sckListen, SOMAXCONN); while(1)
    {
    addrLen = sizeof(addrAccept);
    sckAccept = accept(sckListen, (struct sockaddr*)&addrAccept, &addrLen);
    if(sckAccept==INVALID_SOCKET)
    {
    return 0;
    }       pServer->pWorkParam = new WORKPARAM;
    pServer->pWorkParam->sckClient = sckAccept;
    pServer->pWorkParam->addr = addrAccept; AfxBeginThread(WorkingThread, (LPVOID)pServer, THREAD_PRIORITY_BELOW_NORMAL);
    } return 0;
    }工作线程:UINT CServer::WorkingThread(LPVOID lpVoid)
    {
        int iRet;
        CServer* pServer = (CServer*)lpVoid;
        WORKPARAM* pThreadParam = pServer->pWorkParam; //接收
             //处理
    //发送 closesocket(pThreadParam->sckClient); delete pThreadParam;
    return 0;
    }
      

  3.   

    首先你在线程释放的应该是pServer而不应该是pServer->pWorkParam,这就涉及到一个问题,你的pWorkParam是如何分配内存的,你的pServer又是如何分配内存的?
    你可以把你的相关代码再看看,或者贴出来大家一起讨论。
      

  4.   

    就在delete pThreadParam;这里出错。我反复试过,客户端逐个连接过来没问题,并发连接过来时,delete就出错。不delete的话,不会出错,但可用内存会逐渐减少。
      

  5.   

    Listen 线程:
    {
         int iRet, addrLen;
       sockaddr_in addr, addrAccept;
       SOCKET sckListen, sckAccept;
      char pszMsg[512]; sckListen = socket(AF_INET, SOCK_STREAM, 0);
    iRet = gethostname(pszMsg, 256);
    hostent* pEnt = gethostbyname(pszMsg);
        
    memcpy(&(addr.sin_addr), pEnt->h_addr, pEnt->h_length);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9000);

    iRet = bind(sckListen, (const sockaddr*)&addr, sizeof(addr));
    iRet = listen(sckListen, SOMAXCONN); while(1)
    {
    addrLen = sizeof(addrAccept);
    sckAccept = accept(sckListen, (struct sockaddr*)&addrAccept, &addrLen);
    if(sckAccept==INVALID_SOCKET)
    {
    return 0;
    }       WORKPARAM* pWorkParam = new WORKPARAM;
    pWorkParam->sckClient = sckAccept;
    pWorkParam->addr = addrAccept; AfxBeginThread(WorkingThread, (LPVOID)pWorkParam, THREAD_PRIORITY_BELOW_NORMAL);
    } return 0;
    }工作线程:UINT CServer::WorkingThread(LPVOID lpVoid)
    {
        int iRet;
        WORKPARAM* pThreadParam = (WORKPARAM*)lpVoid; //接收
             //处理
    //发送 closesocket(pThreadParam->sckClient); delete pThreadParam;
    return 0;
    }
      

  6.   

    你的pServer如何分配内存的?你的pServer->pWorkParam又是如何分配内存的?你的问题就出在这,你应该释放的是pServer而不是pWorkParam,把你初始化内存分配pserver和pWorkParam的代码贴出来看看。
      

  7.   

    class CSwDlg : public CDialog
    {
    // Construction
    public:
    CSwDlg(CWnd* pParent = NULL); // standard constructor
    CSServer m_Server;
             .....
    }
    BOOL CSwDlg::OnInitDialog()
    {
    AfxBeginThread(CServer::ListenThread, &m_Server,THREAD_PRIORITY_BELOW_NORMAL);
             ......
    }
    class CServer  
    {
    public:
    CServer();
    virtual ~CServer(); WORKPARAM* pWorkParam;

    public:
    static UINT ListenThread(LPVOID lpVoid);
    static UINT WorkingThread(LPVOID lpVoid);};
      

  8.   

    Listen 线程:
    UINT CServer::ListenThread(LPVOID lpVoid)
    {
         int iRet, addrLen;
       sockaddr_in addr, addrAccept;
       SOCKET sckListen, sckAccept;
      char pszMsg[512]; CServer* pServer = (CServer*)lpVoid;    //这句刚才贴漏了
             ......
    }
      

  9.   

    flyelf(空谷清音) 的代码你好好看看,能解决你的问题。:)
      

  10.   

    flyelf(空谷清音) 的代码确实解决了问题,刚才我还以为他在重贴我的代码,没仔细看。谢谢了!