printf tidak berfungsi dengan baik saat menggunakan utas

hai, ada sedikit masalah dengan printf saat menggunakan utas. Masalahnya adalah terminal mencetak satu pernyataan printf sedikit kemudian yang seharusnya dicetak sebelumnya. ini adalah bagian di mana saya menghadapi masalah ini.

.
.
.
        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
.
.
.

dan ini adalah fungsi yang digunakan thread.

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;
}

dan outputnya seperti ini setiap kali klien (utas) terhubung ke server.

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

ketika klien pertama menghubungkan, output berfungsi dengan baik, tetapi ketika klien kedua menghubungkan string "waiting for a connection" muncul setelah "Received connection". baik itu harus bekerja dengan cara yang kontras. saya akan senang jika Anda dapat membantu dan terima kasih


person quartaela    schedule 04.11.2012    source sumber
comment
Anda mungkin perlu memikirkan fflush(). Anda mungkin perlu memikirkan tentang flockfile() dan funlockfile().   -  person Jonathan Leffler    schedule 05.11.2012
comment
Di mana masalahnya - Saya tidak melihatnya: menunggu/diterima, menunggu/diterima, menunggu. Begitulah cara Anda mengkodekannya dan merupakan hasil yang saya harapkan. Thread penerimaan dimulai, menunggu, kemudian menerima dua koneksi dan kemudian menunggu koneksi lainnya.   -  person Martin James    schedule 05.11.2012
comment
@JonathanLeffler sebenarnya menempatkan fflush(stdout) di atas dan di bawah printf("waiting for a connection\n"); tetapi hasilnya tetap sama   -  person quartaela    schedule 05.11.2012
comment
Itu karena tidak ada yang salah dengan outputnya.   -  person Martin James    schedule 05.11.2012


Jawaban (4)


Tidak ada masalah. Selain pertama kali loop dimasukkan, 'menunggu koneksi' akan menjadi hal terakhir yang dicetak oleh thread penerimaan setelah klien terhubung.

Dengan kata lain, loop ini dimulai/berakhir pada panggilan terima() kecuali saat dimasukkan untuk pertama kali. Ini adalah 'pengecualian' yang pertama kali dilalui, bukan loop berikutnya.

person Martin James    schedule 04.11.2012
comment
ya akhirnya aku menyadari perintah itu benar. salahku :) - person quartaela; 05.11.2012

setbuf(stdout,NULL);
setbuf(stderr,NULL);

Matikan buffering keluaran. printf tidak masuk kembali, sehingga disinkronkan menggunakan kunci global. Ketika output sedang di-buffer, satu thread mungkin tidak melepaskan kuncinya sebelum thread lain mulai mencetak.

Selalu disarankan untuk mematikan buffering keluaran atau hubungi fflush() secara manual, saat melakukan multithreading

person Anirudh Ramanathan    schedule 04.11.2012
comment
saya mencoba menelepon fflush(stdout) tepat di atas dan di bawah pernyataan printf. tapi tidak ada satupun yang berhasil - person quartaela; 05.11.2012
comment
..karena tidak ada yang perlu diperbaiki! - person Martin James; 05.11.2012

Tidak ada masalah (atau setidaknya apa yang Anda uraikan tidak menjadi masalah). Berikut beberapa keluaran beranotasi:

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

Jika Anda sedikit mengubah perulangan while, hasilnya akan terdokumentasi sendiri:

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

Anda mungkin ingin menambahkan ID serupa untuk dicetak oleh thread Anda - misalnya, alih-alih meneruskan satu int yang mewakili soket, berikan struct kecil yang berisi soket dan client_counter (atau `i atau sesuatu yang lebih berguna) nilai pada saat thread dibuat.

person Michael Burr    schedule 04.11.2012
comment
Akhirnya - orang lain mendapatkannya! Saya pikir sayalah yang menjadi gila :) - person Martin James; 05.11.2012
comment
maaf teman-teman, aku belum menyadarinya dan menjadi gila. terima kasih atas jawaban yang mencerahkan :) - person quartaela; 05.11.2012
comment
@quartaela - tidak perlu meminta maaf. Loop yang berhenti di tengah karena pemblokiran panggilan hanyalah salah satu hal multithreading yang akan membuat Anda terbiasa setelah beberapa saat :) - person Martin James; 05.11.2012

Jika Anda mencampur penggunaan stderr dan stdout, Anda tidak dapat mengharapkan pemesanan yang benar kecuali Anda membilasnya setelah digunakan. Segalanya menjadi lebih rumit dengan banyak utas (pembilasan saja tidak cukup), jadi menurut saya Anda harus memilih satu aliran (stdout atau stderr) dan tetap menggunakannya.

person R.. GitHub STOP HELPING ICE    schedule 04.11.2012
comment
apakah ada cara untuk menggunakan keduanya dengan benar_? atau hanya menggunakan salah satunya adalah satu-satunya cara untuk menghindari komplikasi apa pun - person quartaela; 05.11.2012
comment
Jika Anda ingin menggabungkan penggunaan keduanya ketika keduanya mungkin merujuk ke file atau terminal dasar yang sama, Anda akan mendapatkan keluaran yang rusak (mungkin disisipkan secara acak). Satu-satunya cara untuk menghindari hal ini adalah dengan membuat mutex Anda sendiri yang melindungi stdout dan stderr, dan menguncinya kapan pun Anda ingin menulis ke salah satunya. - person R.. GitHub STOP HELPING ICE; 05.11.2012