1

嗨,使用线程时 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

4 回答 4

2

没有问题。除了第一次进入循环外,“等待连接”将是客户端连接后接受线程打印的最后一件事。

换句话说,这个循环在 accept() 调用处开始/结束,除非是第一次进入。这是“异常”的第一次,而不是随后的循环。

于 2012-11-04T22:49:04.937 回答
1
setbuf(stdout,NULL);
setbuf(stderr,NULL);

关闭输出缓冲。printf不是可重入的,因此它使用全局锁进行同步。当输出被缓冲时,一个线程可能不会在另一个线程开始打印之前释放它的锁。

多线程时,始终建议关闭输出缓冲或手动调用fflush()

于 2012-11-04T22:36:31.253 回答
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表示套接字的单个 ID,而是传入一个包含套接字和client_counter(或 `i 或更有用的)值的小结构创建线程的时间。

于 2012-11-04T22:59:22.340 回答
0

如果您混合使用 stderr 和 stdout,除非您在每次使用后刷新,否则您不能期望正确排序。多线程会使事情变得更加复杂(刷新是不够的),所以我认为你应该选择一个流(stdout 或 stderr)并坚持下去。

于 2012-11-04T22:36:56.630 回答