首页 新闻 会员 周边 捐助

linux内核_do_fork()创建子线程后如果是vfork的话怎么确定父线程等待

0
悬赏园豆:100 [已解决问题] 解决于 2023-08-18 17:25

在内核的_do_fork()函数中经过前面的一系列操作后调用 wake_up_new_task(p); 将子线程放入运行队列中开始运行,那么在后面的 wait_for_vfork_done(p, &vfork) 函数不应该是父线程和子线程都会运行一遍该函数,将父线程和子线程的 struct task_struct current 都创建等待队列来进行休眠吗?怎么最后只休眠了父线程啊?求解!

dianyy的主页 dianyy | 初学一级 | 园豆:112
提问于:2023-08-17 16:49
< >
分享
最佳答案
0

当copyProcess之后新的 process已经独立出来了。copy_thread的时候会给它设定新的起始点(也就是他的PC 寄存器的值)。
当 你wake_up_new_task的时候。新的process or thread会从设定的起始位置开始运行。而不是跟 主进程一样。顺着跑起来的。所以后面的wait_for_vfork_done, 只有父进程会跑到。。子进程是跑不到的。

收获园豆:70
会游泳的骆驼 | 菜鸟二级 |园豆:292 | 2023-08-17 17:29

好的,谢谢,另外对于上图pc指针的初始化是这样的吧
copy_process
->copy_thread_tls
->copy_thread
->ret_from_fork
->asmlinkage void ret_from_fork(void) asm("ret_from_fork");
最后跳转到汇编,pc指针将指向调度函数使该线程返回到用户态

dianyy | 园豆:112 (初学一级) | 2023-08-18 17:30
其他回答(1)
0

在 Linux 内核中,do_fork() 函数用于创建一个新的进程或线程(任务)。如果在创建子线程时使用了 vfork,它是一种特殊的 fork,会阻塞父进程,直到子进程调用 exec 系列函数或 _exit 函数。这是因为 vfork 的目的是在子进程中执行一个新的程序,子进程会与父进程共享地址空间,因此父进程需要等待子进程完成。

在 do_fork() 中,当创建子线程时,确实会有一些处理来保证父线程等待子线程的完成,但是并不会通过 wait_for_vfork_done() 函数来进行父线程和子线程都等待的处理。

这是因为 wait_for_vfork_done() 是在 vfork 的子进程中调用的,用于通知父进程子进程已经准备好继续执行了。父进程的等待是通过 vfork_done 标志来完成的。父进程会在 _exit 或者 exec 系列函数调用时被唤醒,然后继续执行。

总之,vfork 通过共享地址空间的方式来实现效率高的创建子进程,但是在子进程执行新程序之前,会阻塞父进程。所以在内核实现中,并不需要父线程和子线程都进入休眠等待状态。子线程执行时会通知父线程,而父线程会在适当的时候恢复执行。

收获园豆:30
Technologyforgood | 园豆:7535 (大侠五级) | 2023-08-17 22:54
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册