簡體   English   中英

為什么printf無法在c中使用多個線程?

[英]Why printf is not working with multple threads in c?

在下面的代碼中,我創建8個線程,每個線程都打印一個字符串及其ID。 但是,我沒有在PrintHello函數的stdout看到任何printf輸出。 發生的一件奇怪的事情是,如果使用調試器(CLion)運行main ,則printf確實會輸出預期的輸出。 我實際上懷疑PrintHello函數中沒有運行任何代碼,而不僅僅是printf 是什么原因造成的?

同樣根據這個答案, printf是線程安全的,因此不同線程競爭stdout不應成為問題。

這是代碼(從這些幻燈片改編而成):

#include <stdio.h>
#include <stdlib.h>
#include <ntsid.h>
#include <pthread.h>
#include <unistd.h>

#define BAD_EXIT 1
#define NUM_TASKS 8

char * messages[NUM_TASKS];

void * PrintHello(void * taskIdPtr) {
    int taskId;
    sleep(1);
    taskId = *((int *) taskIdPtr);
    printf("Task id = %d, message = %s\n", taskId, messages[taskId]);
    free(taskIdPtr);
    pthread_exit(NULL);
}
int main(int argc, char ** argv) {
    pthread_t threads[NUM_TASKS];
    int * taskIdPtr;
    int rc, t;
    messages[0] = "English: Hello World!";
    messages[1] = "French: Bonjour, le monde!";
    messages[2] = "Spanish: Hola al mundo";
    messages[3] = "Klingon: Nuq neH!";
    messages[4] = "German: Guten Tag, Welt!";
    messages[5] = "Russian: Zdravstvytye, mir!";
    messages[6] = "Japan: Sekai e konnichiwa!";
    messages[7] = "Latin: Orbis, te saluto!";

    for(t = 0; t < NUM_TASKS; t++) {
        taskIdPtr = (int *) malloc(sizeof(int));
        *taskIdPtr = t;
        printf("Creating thread %d\n", t);
        rc = pthread_create(&threads[t], NULL, PrintHello, (void *) taskIdPtr);
        if(rc) {
            perror("Error :");
            exit(BAD_EXIT);
        }
    }
    return 0;
}

問題在於您的主線程已完成其執行,並在其他子線程甚至未打印任何消息之前退出(因為在子線程中,您等待1秒鍾才能執行任何操作)。

一旦主線程退出,所有其他子線程也會退出,並且您在屏幕上看不到任何消息。

以下是pthread_create()的Linux手冊頁的摘錄:

新線程以下列方式之一終止

  • 它調用pthread_exit(3),並指定退出狀態值,該值對於調用pthread_join(3)的同一進程中的另一個線程可用。
  • 它從start_routine()返回。 這等效於使用return語句中提供的值調用pthread_exit(3)。
  • 它被取消(請參閱pthread_cancel(3))。
  • 進程中的任何線程都調用exit(3),或者主線程從main()返回 這導致進程中所有線程的終止。

要解決此問題,您應該使用int pthread_join(pthread_t thread, void **retval)

以下是更正的代碼。 看到它在這里工作

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define BAD_EXIT 1
#define NUM_TASKS 8

char * messages[NUM_TASKS];

void * PrintHello(void * taskIdPtr) {
    int taskId;
    sleep(1);
    taskId = *((int *) taskIdPtr);
    printf("Task id = %d, message = %s\n", taskId, messages[taskId]);
    free(taskIdPtr);
    pthread_exit(NULL);
}
int main(int argc, char ** argv) {
    pthread_t threads[NUM_TASKS];
    int * taskIdPtr;
    int rc, t;
    messages[0] = "English: Hello World!";
    messages[1] = "French: Bonjour, le monde!";
    messages[2] = "Spanish: Hola al mundo";
    messages[3] = "Klingon: Nuq neH!";
    messages[4] = "German: Guten Tag, Welt!";
    messages[5] = "Russian: Zdravstvytye, mir!";
    messages[6] = "Japan: Sekai e konnichiwa!";
    messages[7] = "Latin: Orbis, te saluto!";

    for(t = 0; t < NUM_TASKS; t++) {
        taskIdPtr = (int *) malloc(sizeof(int));
        *taskIdPtr = t;
        printf("Creating thread %d\n", t);
        rc = pthread_create(&threads[t], NULL, PrintHello, (void *) taskIdPtr);
        if(rc) {
            perror("Error :");
            exit(BAD_EXIT);
        }
    }

    for(t = 0; t < NUM_TASKS; t++)
    {
        pthread_join(threads[t], NULL);
    }
    return 0;
}

在執行新創建的線程之前,主進程正在退出。 因此,您應該等待使用pthread_join創建的線程。

按照pthread_join的手冊頁

int pthread_join(pthread_t thread, void **retval);

pthread_join()函數等待線程指定的線程終止。 如果該線程已經終止,則pthread_join()立即返回。 線程指定的線程必須是可連接的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM