在使用线程时,printf有一点问题。问题是终端打印一个printf语句稍后应该打印更早。这是我面临这个问题的部分。
.
.
.
while(1){
printf("waiting for a connection\n");
csock = (int*)malloc(sizeof(int));
if((*csock = accept( hsock, (struct sockaddr*)&sadr, &addr_size))!= -1){
printf("---------------------\nReceived connection from %s\n",inet_ntoa(sadr.sin_addr));
client_counter++;
pthread_create(&thread_id,0,&SocketHandler, (void*)csock );
}
else{
fprintf(stderr, "Error accepting %d\n", errno);
}
}// end while
.
.
.
这是线程'使用的函数。
void* SocketHandler(void* lp){
int *csock = (int*)lp;
char buffer[1024];
int buffer_len = 1024;
int bytecount;
char* str_exit="exit";
while(1){
memset(buffer, 0, buffer_len);
if((bytecount = recv(*csock, buffer, buffer_len, 0))== -1){
fprintf(stderr, "Error receiving data %d\n", errno);
exit(0);
}
if(strcmp(buffer,str_exit)==0){
break;
}
printf("Received bytes %d\nReceived string \"%s\"\n", bytecount, buffer);
strcat(buffer, " SERVER ECHO");
if((bytecount = send(*csock, buffer, strlen(buffer), 0))== -1){
fprintf(stderr, "Error sending data %d\n", errno);
exit(0);
}
//printf("Sent bytes %d Sent String %s\n", bytecount,buffer);
}
printf("Client disconnected\n");
free(csock);
return 0;
}
,只要客户端(线程)连接到服务器,输出就像这样。
waiting for a connection
---------------------
Received connection from 127.0.0.1
waiting for a connection
Client disconnected
---------------------
Received connection from 127.0.0.1
waiting for a connection
Client disconnected
当第一个客户端连接输出正常工作时,但当第二个连接字符串"waiting for a connection"
时,"Received connection"
之后。那么它应该以相反的方式工作。如果你能提供帮助和感谢,我将很高兴
答案 0 :(得分:2)
没有问题。除了第一次输入循环之外,'等待连接'将是客户端连接后接受线程打印的最后一件事。
换句话说,这个循环在accept()调用开始/结束,除非是第一次输入。这是第一次通过“异常”,而不是后续循环。
答案 1 :(得分:1)
setbuf(stdout,NULL);
setbuf(stderr,NULL);
关闭输出缓冲。 printf 不可重入,因此它使用global-locks进行同步。 当缓冲输出时,一个线程可能在另一个线程开始打印之前不会释放它。
多线程
时,始终建议 turn off output buffering 或手动调用fflush()
答案 2 :(得分:1)
没有问题(或者至少你所描述的不是问题)。这是一些带注释的输出:
waiting for a connection # 1
--------------------- # 1
Received connection from 127.0.0.1 # 1
waiting for a connection # 2
Client disconnected # thread handling connection 1
--------------------- # 2
Received connection from 127.0.0.1 # 2
waiting for a connection # 3
Client disconnected # thread handling connection 2
如果稍微更改while循环,输出将变为自我记录:
int i = 0;
while(1) {
printf("%d: waiting for a connection\n", i);
csock = (int*)malloc(sizeof(int));
if((*csock = accept( hsock, (struct sockaddr*)&sadr, &addr_size))!= -1) {
printf("%d: ---------------------\n%d: Received connection from %s\n",
i, i, inet_ntoa(sadr.sin_addr));
client_counter++;
pthread_create(&thread_id,0,&SocketHandler, (void*)csock );
}
else{
fprintf(stderr, "%d: Error accepting %d\n", i, errno);
}
++i;
}// end while
您可能希望为线程添加一个类似的ID来打印 - 例如,不是传入代表套接字的单个int
,而是传入一个包含套接字和{{1}的小结构在创建线程时的值(或者我或者更有用的东西)。
答案 3 :(得分:0)
如果你混合使用stderr和stdout,除非你在每次使用后冲洗,否则你不能指望正确的排序。多线程的事情变得更加复杂(刷新是不够的),所以我认为你应该选择一个流(stdout或stderr)并坚持下去。