1

こんにちは、スレッドの使用中にprintfに少し問題があります。問題は、ターミナルが1つの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

最初のクライアントが接続すると出力は正しく機能しますが、2番目のクライアントが接続すると文字列"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を追加して出力することもできます。たとえば、ソケットを表す単一のIDを渡す代わりに、ソケットと(または `iまたはより便利な)値intを含む小さな構造体を渡します。client_counterスレッドが作成された時刻。

于 2012-11-04T22:59:22.340 に答える
0

stderrとstdoutの使用を混合している場合、使用するたびにフラッシュしない限り、適切な順序付けを期待することはできません。複数のスレッドを使用すると事態はさらに複雑になるため(フラッシュでは不十分です)、1つのストリーム(stdoutまたはstderr)を選択してそれを維持する必要があると思います。

于 2012-11-04T22:36:56.630 に答える