Winsock多客户端和多线程,计算机努力工作

Winsock multi clients and multi thread, Computer works hard

本文关键字:计算机 努力 工作 多线程 客户端 Winsock      更新时间:2023-10-16

我正在尝试在C 插座编程中构建多客户端服务器,并且在多线程中发现了一些麻烦。我使用_beginthread创建一些线程。当我们想构建多样服务器时,我认为我们应该有一个线程,可以随时处理套接字ACCEPTER,到目前为止,它可以正常工作(对我来说没问题)。

之后,我制作了一些线程来处理 client-datareceiver ,我认为它比我们创建1个线程更好地处理所有客户端。我认为,多线程会更好,因为它们同步工作。

当我完成所有操作时,服务器工作得如此缓慢/硬,甚至可以使用100%CPU使用?也许我的代码上有一些缺少/错误?

   void Initialize(){
      [....Server initialize goes here...]
       _beginthread( acceptNewClient, 0, (void*)1);  //the thread that handle accepter
    }
    SOCKET ClientSocket;
    void acceptNewClient(void* arg)
{
    while(true){
    ClientSocket = accept(ListenSocket,NULL,NULL);
    if (ClientSocket != INVALID_SOCKET) 
    {
        char value = 1;
        setsockopt( ClientSocket, IPPROTO_TCP, TCP_NODELAY, &value, sizeof( value ) );
        Client_Socket *client = new Client_Socket(ClientSocket); 
        _beginthread(ReceiveFromClient, 1,client );   //handle of client data receiver
        client_list.push_back(client);
    }
  }     
}
void ReceiveFromClient(void* client_sockets)
{
   Client_Socket * client_socket = (Client_Socket*)client_sockets;
   while(true){
       server->doReceive();    
   }
}

编辑:

弄清楚这种情况后,我认为CAUSER是线程本身我什至尝试了新的控制台项目:

#include <process.h>
    void tes(void * arg){
        while(true){
        }
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
    _beginthread( tes, 0, (void*)1);
    _beginthread( tes, 0, (void*)1);
    _beginthread( tes, 0, (void*)1);
    _beginthread( tes, 0, (void*)1);
    _beginthread( tes, 0, (void*)1);
    _beginthread( tes, 0, (void*)1);
    _beginthread( tes, 0, (void*)1);
    _beginthread( tes, 0, (void*)1);
    _beginthread( tes, 0, (void*)1);
    _beginthread( tes, 0, (void*)1);
    _beginthread( tes, 0, (void*)1);
    _beginthread( tes, 0, (void*)1);
    while(true){}
        return 0;
    }

线程对于计算机来说太难了,我认为错误是线程本身。这些代码确实使CPU 100%CPU,我的线程代码或解决方案解决此情况有问题吗?

正如我在几个小时前暗示的那样,原因是由于某种原因,您已将插座放入非阻滞模式,而您不使用select(),只需旋转围绕RECV()循环。无论如何,这都是没有意义的,因为您每次连接都使用线程。

根据您的答案,该解决方案不是将套接字放回阻塞模式,而是要删除 emove 首先设置非阻止模式的代码,阻止模式为默认模式,如@chao所指出的。

100%CPU很可能是由循环引起的(while(true) server->doReceive();)。使用套接字的正确方法是在插座上等待,直到对其进行有用的操作。标准C 函数可以启用这是select

更高级的方法是使用I/O完成端口,但是在您的阶段,技术太先进了,甚至可能不需要。

我发现了问题。首先,如果您想使用每个客户端构建服务器,那么第一件事必须知道的是:

确保已使用ioctlsocket事先将插座设置为阻塞模式

这实际上是非常有意义的!好吧,当我们创建这样的线程时:

unsigned __stdcall threadFunc(void * arg) 
{   
    while(1) {
    }
    return 0;
}

看起来很简单的线程代码,但是导致CPU的工作非常努力。当recv winsocks的函数以非阻止模式调用时,当没有更长的数据读取数据时,它们将始终重复对while表示,它们会像comp一样快速地旋转。当然,这不是好主意。因此,如果我们想克服它,当然正确的方法是:将插座设置为非块。

u_long iMode = 0;
iResult = ioctlsocket(ClientSocket, FIONBIO, &iMode);

当recv()插座时,调用机器将等到他们有一些字节要读取。以这种方式"快速旋转"将不再发生

反正谢谢..

相关文章: