使用线程时printf无法正常工作

时间:2012-11-04 22:32:28

标签: c multithreading posix

在使用线程时,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"之后。那么它应该以相反的方式工作。如果你能提供帮助和感谢,我将很高兴

4 个答案:

答案 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)并坚持下去。