2

我创建了 3 个线程,每个线程都有一个套接字。在每个线程内部,套接字都是“事件驱动”的,只要数据可供读取,就会生成一个事件。

代码运行良好,但 CPU 使用率高达 100%,这肯定是不可取的。我想我犯了一些错误。下面是我的代码。请帮助我找出导致 100% CPU 使用率的错误。

代码:

DWORD WINAPI ThreadProc(LPVOID param)
{
   int threadNumber= (int)param;
   int PORT = 8888+threadNumber; //so that each thread bind()s its socket to a different Port number.
   WSADATA wsa; 

   //Initialise winsock//
   if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
      {

        //"WinSock Initialization FAILED",

      }

   //Create a socket//

  SOCKET newSocketIdentifier;
  SOCKADDR_IN newSocket;

  if((newSocketIdentifier = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
      {                 

        //Socket Creation Failed

      }
   //Socket Created//

   //Prepare the sockaddr_in structure//
  newSocket.sin_family = AF_INET;
  newSocket.sin_addr.s_addr = INADDR_ANY;
  newSocket.sin_port = htons(PORT);

   //Bind//
   if( bind(newSocketIdentifier ,(struct sockaddr *)&newSocket, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
      { 
       //Bind Failed
      }

   //Bind Done//
char data[256];
int bytes, waitRet;

WSAEVENT hEvent = WSACreateEvent();
WSANETWORKEVENTS events;
WSAEventSelect(newSocketIdentifier, hEvent, FD_READ | FD_WRITE);

   while(1)
      {
         waitRet = WSAWaitForMultipleEvents(2, &hEvent, FALSE, WSA_INFINITE, FALSE);
         if(WSAEnumNetworkEvents(newSocketIdentifier,hEvent,&events) == SOCKET_ERROR)
            //Error
         else
            {
               if(events.lNetworkEvents & FD_READ)
                  {
                      //call recvfrom()
                  }
            }
      }

    WSACloseEvent(hEvent);
   return 0;
}

int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{

   HANDLE threadHandle[3];
   DWORD threadId = 0;
   int max_number=3;
   //Start the threads
   for (int i = 0; i < max_number; i++) 
   {
    threadHandle[i]= CreateThread( NULL,
                                       0,
                                       ThreadProc,
                                       (LPVOID) i,
                                       0,
                                       NULL
                                 );
   }

return 0;
}
4

1 回答 1

3

这是一个错误:

waitRet = WSAWaitForMultipleEvents(2, &hEvent, FALSE, WSA_INFINITE, FALSE);

因为它说明提供的事件数组中有两个事件,但事实并非如此,因为只有 1 个。从WSAWaitForMultipleEvents()描述第一个参数的参考页面:

lphEvents 指向的数组中事件对象句柄的数量。事件对象句柄的最大数量是 WSA_MAXIMUM_WAIT_EVENTS。必须指定一个或多个事件。

我怀疑这会导致未定义的行为,因为WSAWaitForMultipleEvents()访问超出了数组的范围,可能导致函数不会阻塞,从而导致繁忙的循环。

此外,请参阅Rohan关于WSAResetEvent().

于 2013-05-07T11:35:51.950 回答