在下面的代码中,我创建了 8 个线程,每个线程都打印一个字符串及其 ID。但是,我没有在 PrintHello
函数的 stdout
中看到任何 printf
输出。正在发生的一件奇怪的事情是,如果使用调试器 (CLion) 运行 main
,printf
确实会输出预期的输出。我实际上怀疑 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/