level 3
我用xshell连了Ubuntu,版本好像是22.04
就是我今天刚学线程,写了一个很简单的代码,就是在main里创建一个线程,主函数打印一句话,比如我是主函数,然后线程调用的函数中也只打印一句话,比如我是线程,我的理解是没有手动分顺序,线程这句话有时候没抢过主函数所以会打印不出来,有时候会先打印,这都很正常,但是会出现一种情况我不理解,就是先打印我是主函数,然后接着打印两次我是线程。我问ai,ai老说我偷偷打印了两次啥的,所以请教一下广大吧友,现在手头没电脑,不好贴图。
省流版:创建线程后线程内的printf打印会打印两次,不明白为什么会打印两次。
2026年06月12日 10点06分
1
level 10
haulm』$ gcc b.c
『haulm』$ cat b.c
#include <stdio.h>
#include <pthread.h>
void *thread_func(void *arg) {
printf("I am son\n");
return NULL;
}
int main(int argc, char *argv[]) {
printf("hello\n");
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_func, NULL);
pthread_join(thread_id, NULL); // ← 就这一行,圈养关键
printf("I am main\n");
return 0;
}
『haulm』$ ./a
hello
I am son
I am main
『haulm』$ ./a
hello
I am son
I am main
『haulm』$ ./a
hello
I am son
I am main
『haulm』$ ./a
hello
I am son
I am main
『haulm』$ ./a
hello
I am son
I am main
『haulm』$
2026年06月12日 18点06分
5
你少的那一句,结果就是主程序并没有等到子程序执行就完成退出了,永远不可能打印子线程,当你多次执行后,能够打印两次,那是很奇怪的事情。只有循环的程序,才能正常执行这个代码,否则你只能用 join 堵塞主程序等待返回。你要更好地得到结果,一般要使用界面程序,不会马上退出的程序,你用单程指令程序去测试,它是直线的,不等子线程返回就结束了。
2026年06月12日 19点06分
@素虬ლ 哥你说的这个我是理解的,我只是对我的贴图的代码会出现两次打印感到疑惑
2026年06月13日 00点06分
我记得join后是主线程退出后子线程也结束。出现打印两次sin的情况,可能是在执行i am main 前子线程执行了两次,这是有概率的
2026年06月13日 01点06分
回复 starcat2008 :可是代码只运行了一次线程,第二次运行线程的情况是什么造成的呢
2026年06月13日 01点06分
level 10
// 主线程可以阻塞等待
pthread_create(&tid, NULL, unzip, NULL);
pthread_join(tid, NULL); // OK,反正后面没别的事
printf("解压完成\n");
也就是说你这种单程的主线程,用它来堵塞等待子线程的执行完成,如果是一个界面程序,那考虑就更多了。你的原因主要是主线程退出了,子线程还没执行完。
2026年06月12日 19点06分
6
level 10
这样
static int son_done = 0;
void *thread_func(void *arg) {
printf("I am son\n");
son_done = 1; // 完成时设置标志
return NULL;
}
int main() {
pthread_create(&tid, NULL, thread_func, NULL);
while (1) {
if (son_done) {
// 子线程完成了,处理结果
printf("son finished, updating UI...\n");
break; // 或者继续做别的事
}
handle_user_input();
update_animation();
// ... 等等
}
return 0;
}
2026年06月12日 19点06分
8
还有一个问题就是,之前学进程的时候都没有出现过这个问题,我觉得主要还是因为没人抢CPU的执行时间,如果fork的父子进程,假设让子进程打印,父进程杀死进程,是不是也有可能会像线程这样打印两次呢
2026年06月13日 00点06分
@蟹大虾OvO 讲 fork 的是进程,不是线程。今天也因为这个讨论,我把自己一团混乱的安装器给梳理清楚了。也是进程和线程混杂。线程比进程代价小十倍左右,但线程一出错会所有线程崩溃,而进程只影响进程本身。
2026年06月13日 04点06分
@蟹大虾OvO 线程打印多次不用纠结啦,那是你的系统环境问题,正常你关注正确的线程操作方法,避免让线程不受控制,线程并行,不设置标志位,你根本就不知道哪个先,哪个后。你要用线程,你肯定要学会怎么控制它,而且一个崩溃了,所有的线程都完蛋了。如果用进程,一个进程就是一个进程,进程就简单多了。进程虽然可以并行,但是各个进程是独立的,缺点就是很占资源。
2026年06月13日 04点06分