0
 main() {
    unsigned int newfd;
    ...
    .....
    while (1) {        
      printf("Waiting for connection\n");
      addrlen = sizeof (clientaddr);
      if ((newfd = accept(listener, (struct sockaddr *) &clientaddr, &addrlen)) < 0) {
          perror("Server-accept() error lol!");
          break;
      }
      printf("New connection from %s on socket %u\n", inet_ntoa(clientaddr.sin_addr), newfd);
      pthread_create(&threads[i++], NULL, (void*)fileTransfer_Worker, &newfd); 
      sleep(1);
   }

}

void* fileTransfer_Worker(void *desc) {
     unsigned int sock = *(unsigned int *) desc;
     printf("Waiting for data in sock %d %u\n", sock, pthread_self());
}

输出

Waiting for connection
New connection from 192.168.4.57 on socket 4
Waiting for connection
New connection from 192.168.4.57 on socket 5
Waiting for connection
Waiting for data in sock 4 3076578160
Waiting for data in sock 5 3068189552
New connection from 192.168.4.57 on socket 6
Waiting for connection
Waiting for data in sock 6 3059800944
New connection from 192.168.4.57 on socket 7
Waiting for connection
New connection from 192.168.4.57 on socket 8
Waiting for connection
New connection from 192.168.4.57 on socket 9
Waiting for connection
Waiting for data in sock 8 3051412336
New connection from 192.168.4.57 on socket 10
Waiting for data in sock 9 3034635120
Waiting for data in sock 10 3043023728
Waiting for connection
New connection from 192.168.4.57 on socket 11
Waiting for connection
New connection from 192.168.4.57 on socket 12
Waiting for connection
New connection from 192.168.4.57 on socket 13
Waiting for connection
Waiting for data in sock 13 3001080688
Waiting for data in sock 13 3026246512
Waiting for data in sock 13 3017857904
Waiting for data in sock 13 3009469296

如果查看输出,您会注意到 sock 13 显示了 4 次,实际上应该是套接字 7、11、12 和 13。

每次我同时调用更多客户端连接时,行为都会发生变化。

如果我在 pthread_create() 之后添加 sleep(1),那么我能够看到预期的行为。pthread_create 之后的睡眠是必须的吗?或者如何在不使用睡眠的情况下解决此问题?

帮我解决这个问题。提前致谢

4

1 回答 1

2
pthread_create(&threads[i++], NULL, (void*)fileTransfer_Worker, &newfd);
                                                                ^^^^^^

问题是您将局部变量的地址传递给pthread_create. 当线程开始使用它时,main可能已经改变了它。因此,如果描述符是10在您调用pthread_create时,那么当线程实际开始使用时main已经有机会更改它。

您至少有 2 个选项可以解决此问题:

  • 为每个线程传递一个单独的对象(可能是你的一个malloc
  • 在参数中填充整数,就好像它是 a 一样void *,然后int在线程函数中转换回

尽管第二种选择被广泛使用,但它也是不可移植的。

于 2012-08-20T08:03:46.150 回答