[英]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.