最近遇到一个很头痛的问题,让我耽误了不少时间,还是不知道问题的原因。
我做的是一个C/S中的服务器端,服务器端接受客户端连接并进行数据处理。因为客户端很多,最终可能同时有上千台进行连接,为了提高服务器端的数据处理能力,我使用了线程池和连接池的方法。如果有客户端连接,从连接池中取出一个空闲状态的连接,Accept(连接)以后,将此连接放入线程池中的任务链表。线程池中有一个无限循环,检测到有新任务就选择一个空闲的工作线程,由该工作线程处理该连接。
基本的思路就这样,线程池和工作线程都是继承自CWinThread的类,改写了Run函数,Run是个无限循环,工作线程用他来重复完成任务,线程池用他来监测任务链表。
现在遇到这样一个问题,连接任务处理完毕后(现在还未编写处理函数,只是一个空函数),执行连接的关闭操作(->Close()),就出现错误了,调试发现该连接在添加到任务列表前都可以Close(),而放在Run中就不行。
请大家帮我分析一下是什么原因造成,或给我提供一个多线程处理客户连接的范例,先谢了。

解决方案 »

  1.   

    你在RUN中是怎样判断函数处理结束的?
      

  2.   

    Run函数分派线程的Message,CAsyncSocket函数是靠Message的异步IO,你把RUN改成无限循环,CAsyncSocket如何能够收到Windows的Message,收不到MessageCAsyncSocket就不能工作了,这个问题很明显
      

  3.   

    再说明一下我的程序。我的Run函数不用接受消息的,不是通过发送消息来通知是否有任务到来,而是一直检测任务链表,有任务就进行处理。部分代码我贴出来。
    这是线程池的Run函数
    int CThreadPool::Run() 
    {
    int i;
    CWorkThread* pThread;
    CClientSocket* pClientSocket; while(!m_bExit)//如果不允许退出,无限循环执行
    {
    i=m_listTask.Count();//检查任务列表中任务数量
                      if(i>0) //如果有任务
    {
    //从线程池取一个空闲工作线程,没有则等到有为止
    while((pThread=GetThread())==NULL);
    //从列表中取一个任务
    pClientSocket=(CClientSocket*)m_listTask.RemoveHead();
    //下面这行是测试用的,也就是执行这行有问题
    pClientSocket->Close();
    //给工作线程分配任务
    pThread->SetTask(pClientSocket);
    }
    } return 0;
    }
    在我的工作线程和连接Socket里都有一个标志,表示是否处于空闲状态。
    出现错误的地方就是pClientSocket->Close();本来这里是不需要这行代码的,本来应放在工作线程中完成任务后再关闭。就是因为那里面有错误,才放到这里来调试。
    该关闭操作不放在Run里就没问题。
      

  4.   

    AddTask函数是向线程池中添加任务,在这个函数里面加上
    pClientSocket->Close();
    不会有问题,可以正常关闭。
    void CThreadPool::AddTask(CClientSocket *pClientSocket)
    {
    m_listTask.AddTail(pClientSocket);
    //测试用,要删除下一行
    pClientSocket->Close();
    }
    请大家帮我分析一下原因。
    快过年了,我想过个好年。
      

  5.   

    更本出现机会WSAGetLastError的机会,错误出现后弹出一对话框,然后结束
      

  6.   

    还是象前面说的,CAsyncSocket是靠 Windows Message来实现异步Socket IO的,如果你是在线程里生成CAsyncSocket,你在线程RUN里CLOSE CAsyncSocket出现问题的可能肯定很大,因为你破坏了CAsyncSocket的消息机制
      

  7.   

    TO cxu123(cxu):
    不太明白你说的意思,可以上QQ聊下吗,我的QQ:37957592
      

  8.   

    CAsyncSocket实际用的是WSAAsyncSelect方式,如下"After your application successfully calls WSAAsyncSelect on a socket, the application begins to receive network event notification as Windows messages in the window procedure associated with the hWnd parameter window handle. "在Network Programming for Microsoft Windows这本书的Winsock I/O Methods一章里,看了就明白了
      

  9.   

    pClientSocket->Close()关闭之后,线程自动回送 OnClose Notification Message,你的RUN改成无限循环,这个OnClose Notification送不出去