pthread_mutex_lock 100% cpu?

3

代码:

local void*
s_accept_connections(tmpsock)
  void* tmpsock;
{
  int32_t newfd;
  int32_t tmp;
  SOCKADDR_IN newsockaddr;
  pthread_t id;
  Connection* newconn;
  const char *s;
  char **splited;
  int i;
  StringVec *p;
  StringVec* next;
  Socket* sock;
  tmp = sizeof(newsockaddr);
  p = NULL;
  next = NULL;
  sock = (Socket *)tmpsock;
  if (!sock)
   return 0;

  while (true){
    newfd = accept(sock->fd,(SOCKADDR *)&newsockaddr,&tmp);
    if (newfd <0){
        if (check_error_async()){
            pthread_mutex_lock(&g_socket_mutex);
#ifdef _WIN32
            Sleep(1000);
#else
            sleep(1);
#endif
            pthread_mutex_unlock(&g_socket_mutex);
            continue;
        }
    }else{
        newconn = (Connection *)MyMalloc(sizeof(*newconn));
        newconn->fd = newfd;
        newconn->addr = newsockaddr;
        s = (const char *)inet_ntoa(newsockaddr.sin_addr);
        p = split_string(s,".");
        if (p != NULL){
            splited = (char **)MyMalloc(sizeof(*splited) + 12);
            i = 0;
            for (; p != NULL; p = next){
                if (p && p->next){
                    next = p->next;
                }else{ break; }
                    splited[i] = p->value;
                    i++;
                } 
                newconn->ip = swap_uint32_t((uint32_t)(atoi(splited[0])) + (atoi(splited[1]) << 8) + (atoi(splited[2]) << 16) + (atoi(splited[3]) << 24));
                MyFree((char *)splited);
        }else{
            newconn->ip = 0;
        }
        newconn->closed = false;
        newconn->state = 0;
        newconn->state |= S_NEED_LOGIN;
        pthread_mutex_init(&g_ping_mutex,NULL);
        pthread_cond_init(&g_ping_cond,NULL);
        pthread_create(&id,NULL,s_ping_thread,(void *)newconn);
        a_conn(&sock->conn,newconn);
#ifndef NDEBUG
        _("Accepting connection...\n");
#endif
        if (sock->has_callback){
            sock->func(newconn);
#ifndef NDEBUG
            _("Accepted connection\n");
#endif 
        }
    }
   }
    return 0;
}

    void
    start_accept(sock,join)
      Socket* sock;
      bool join;
    {
      pthread_t id;
      pthread_attr_t attr;
      if (!sock)
       return;
      if (!sock->conn){
        sock->conn = (Connection *)MyMalloc(sizeof(*sock->conn));
        if (!sock->conn)
          return;
      }
      set_nonblocking(sock->fd);
      set_nonblocking(sock->conn->fd);
      pthread_attr_init(&attr);
      pthread_mutex_init(&g_socket_mutex,NULL);
      if (join){
        pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
      }else{
        pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
      }
      pthread_create(&id,&attr,s_accept_connections,sock);
      if (join){
        pthread_join(id,NULL);
        pthread_attr_destroy(&attr);
        pthread_mutex_destroy(&g_socket_mutex);
      }
    }

它只是占用了100%的CPU,有什么想法吗?如果需要更多代码,我会发布。

1个回答

4

您认为pthread_mutex_lock()是导致CPU使用率高的原因吗?

使用调试器找出问题所在。我猜测可能是您的套接字存在问题,导致accept()呼叫非阻塞。

检查返回值/消息(如果您正在运行Linux,则使用perror())。

编辑:

您需要知道哪一段代码在循环调试器可以帮助您找到它。

您有一个while(true)循环,很可能是导致无限循环和100% CPU使用率的原因。这应该没关系,因为您调用了accept()(在此处:newfd = accept(sock->fd,(SOCKADDR *)&newsockaddr,&tmp);),这将停止线程/进程,直到下一个客户端连接。但是,如果未正确初始化套接字,则accept()可能会在等待之前返回错误。


我不明白为什么在这种情况下我应该使用调试器...它没有崩溃。而且为什么pthread_mutex_lock不负责CPU使用?我应该怎么做才能防止这种情况发生?你说的"你的accept()调用是非阻塞的"是什么意思? - user502230
@Ben:我的套接字是非阻塞的,并且已经正确设置,我可以成功连接。 - user502230
1
你有一个while(true)循环,里面没有阻塞调用,为什么你期望的不是100%的CPU使用率?(pthread_mutex_lock()除非另一个线程持有互斥锁,否则不会阻塞) - Ben
@Fallen 我假设 sleep() 函数正常工作,你确定它被调用了吗? - Ben
@Fallen:我看了一下,你的代码里有很多if语句。根据check_error_async()返回的值不同,它可能不会被调用。如果你确定它被调用了,那么我也不知道还有什么其他问题了。 - Ben
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接