c - 为什么 printf 不能在 c 中使用多线程?

标签 c multithreading pthreads printf pthread-join

在下面的代码中,我创建了 8 个线程,每个线程都打印一个字符串及其 ID。但是,我没有在 PrintHello 函数的 stdout 中看到任何 printf 输出。正在发生的一件奇怪的事情是,如果使用调试器 (CLion) 运行 mainprintf 确实会输出预期的输出。我实际上怀疑 PrintHello 函数中没有代码运行,而不仅仅是 printf。可能是什么原因造成的?

也是根据这个answer printf 是线程安全的,因此它不应该是不同线程竞争 stdout 的问题。

这是代码(改编自这些 slides ):

#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 手册页的摘录:

The new thread terminates in one of the following ways:

  • It calls pthread_exit(3), specifying an exit status value that is available to another thread in the same process that calls pthread_join(3).
  • It returns from start_routine(). This is equivalent to calling pthread_exit(3) with the value supplied in the return statement.
  • It is canceled (see pthread_cancel(3)).
  • Any of the threads in the process calls exit(3), or the main thread performs a return from main(). This causes the termination of all threads in the process.

要解决此问题,您应该使用 int pthread_join(pthread_t thread, void **retval) .

以下是更正后的代码。看吧working here :

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

关于c - 为什么 printf 不能在 c 中使用多线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50133647/

相关文章:

c - fork() - 关闭服务器

c - 返回指针并在 C 中释放它时发生内存泄漏

c - sscanf() 跳过分隔符和宽度

C Primer Plus 第 6 章练习 4 检查

c# - STAThread 和多线程

node.js - Nodejs - 可以在线程池大小为 4 的同时运行的最大线程是多少?

c# - WPF C# 长时间运行操作

c++ - 使用 pthread_create 时出现 "Segmentation fault (core dumped)"

linux - 如何使用毫秒级的 pthread_cond_timedwait

multithreading - 在不涉及先前数据计算的情况下更改变量是否是线程安全的?