0

下面的代码怎么能

while(1) {
  client_name_len = sizeof(struct sockaddr_in);
  newsockfd = accept(sockfd, (struct sockaddr *)&client_name, &client_name_len);
  if (newsockfd < 0) {
    perror("ERROR on accept");
    printf("Finished\n");
    close(sockfd);
    exit (EXIT_FAILURE);
  }
  printf("a:");
  pthread_t thread1;
  int *addr = (int*)malloc(sizeof(int));
  *addr = newsockfd;
  pthread_create( &thread1, NULL, &ProcessClient, (void*)addr);
}

产生以下输出:

a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:ERROR on accept: Too many open files
a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:Finished

问题是perror("ERROR on accept"),printf("Finished\n")printf("a:")在同一个线程中执行,但输出是混合的。

ProcessClient 不输出任何内容,也不创建任何线程。 sockfd是一个标准的监听 tcp 套接字。

4

2 回答 2

2

和是缓冲 I/O 到标准输出printf("a:");printf("Finished\n");

perror("ERROR on accept");是无缓冲(或立即刷新)的 I/O 到 stderr。

所以在'eda:之后出现的许多 '之前ERROR on accept: Too many open files实际上是printf()'ed,但是缓冲使它们稍后出现在控制台上。

有关解决问题的详细信息和方法,请参见https://stackoverflow.com/a/3746795/12711

于 2012-08-18T16:49:28.973 回答
1

正如迈克尔指出的那样,第一个问题是您使用了两个不同的流(stdout 和 stderr),一个是缓冲的,另一个是无缓冲的。但是,您还将输出分解为多个 stdio 调用,这使其成为非原子的。我会建议将其替换为perror

printf("ERROR on accept: %s\n", strerror_l(errno));

或将其他printf调用切换为使用fprintfon stderr,以便您在写入哪个流时保持一致。

然后,为了使其具有原子性,请flockfile(f)在函数的开头和funlockfile(f)返回之前调用(其中f替换为您选择使用的任何一个)stdoutstderr或者,如果您仍然想同​​时使用两者,则可以将它们都锁定...

于 2012-08-18T20:05:27.770 回答