无话不谈|离 Linux 内核有多远?,Java( 四 )
FUNC(%esp)对应&start_thread ,
STACK(%esp)对应stackaddr ,
ARG(%esp)对应pd(新进程传递给start_thread的参数) 。
第1步 , 将新进程的栈stackaddr赋值给ecx , 确保它的值不为0 。 第2步 , 将pd、&start_thread和0存入新线程的栈 , 对当前进程的栈无影响 。 第3步 , 将当前进程的三个寄存器的值入栈 , esp寄存器的值相应减12 。 第4步 , 准备系统调用 , 其中将FLAGS+12(%esp)存入ebx , 对应clone_flags , 将clone的系统调用号存入eax 。 第5步 , 将clone_flags存入新进程的栈中 。 第6步 , 使用int指令发起系统调用 , 交给内核创建新线程 。 截止到此处 , 所有的代码都是当前进程执行的 , 新线程并没有执行 。 从第7步开始的代码 , 当前进程和新线程都会执行 。 对当前进程而言 , 程序将它第3步入栈的寄存器出栈 。 但对新线程而言 , 它是从内核的ret_from_fork执行的 , 切换到用户态后 , 它的栈已经成为stackaddr了 , 所以它的edi等于clone_flags , esi等于0 , ebx等于&start_thread 。 系统调用的结果由eax返回 , 第8步判断clone系统调用的结果 , 对当前进程而言 , clone系统调用如果成功返回的是新线程在它的pidnamespace中的id , 大于0 , 所以它执行ret退出__clone函数 。 对新线程而言 , clone系统调用的返回值等于0 , 所以它执行L(thread_start)处的代码 。 clone_flags的CLONE_VM标志被置位的情况下 , 会执行call*%ebx , ebx等于&start_thread , 至此start_thread得到了执行 , 它又调用了提供给pthread_create的start_routine , 结束 。 ”如此看来 , Java→JVM→glibc→内核 , 好像也没有多远 。
推荐阅读
- 无话不谈|全球5G基站建设数量大曝光!中国建成50万个:那欧美国家呢?
- 无话不谈|心动不如行动,赶紧保存,分享一些好看到极致的全面屏手机壁纸
- 无话不谈|已经没有国家能够扼杀中国高端科技,中国芯片崛起已成既定事实
- 通天战队|没有之一,Linux:NVIDIA是我们接触过的最糟糕的公司
- 载风月|关闭终端,程序后台运行,我有5种方法你呢?,Linux运维之
- 小米科技|Linux系统下Java通过shell脚本监控重启服务
- 少年帮|Linux 版已上架统信 UOS 商店,迅雷下载
- 无话不谈|五千电池+128GB,低至1399元,三款超长续航5G手机
- 莫小帅|kernel同步机制(上篇),Linux
- Linux|Linux迎来29周年,我们一起看下Linux一路过来的发展(第一部)