以下代码如何
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套接字。
答案 0 :(得分:2)
printf("a:");
和printf("Finished\n");
缓存I / O转到stdout。
perror("ERROR on accept");
未缓冲(或立即刷新)I / O转到stderr。
所以a:
之后显示的ERROR on accept: Too many open files
之前的printf()
实际上是{{1}}',但缓冲会让它们稍后出现在控制台上。
有关解决问题的详细信息和方法,请参阅https://stackoverflow.com/a/3746795/12711。
答案 1 :(得分:1)
正如迈克尔所指出的,第一个问题是你正在使用两个不同的流(stdout和stderr),而另一个是缓冲的,而另一个是无缓冲的。但是,您还将输出分解为多个stdio调用,这使其成为非原子的。我建议将perror
替换为:
printf("ERROR on accept: %s\n", strerror_l(errno));
或切换其他printf
来电fprintf
使用stderr
,以便您对要撰写的信息流保持一致。
然后,为了使其成为原子,请在函数开头调用flockfile(f)
并在返回之前调用funlockfile(f)
(其中f
被stdout
或{替换为stderr
{1}}你选择使用)。或者如果你真的想要同时使用它们,你可以锁定它们......