图说Linux进程之三

以下内容已屏蔽图片优化访问速度
图说Linux进程



图说Linux进程之二



五、计算机体系结构相关数据


在task_struct里面有一个thread_info


[IMG]


[IMG]


为什么需要单独的这个数据结构呢?因为不同的体系结构可能会有不同的实现。


[IMG]


从代码可以看出不同的体系结构有不同的实现。


[IMG]


在thread_info里面有一个指针指向task_struct。


这个指针有什么用的,当一个用户态的进程进入到内核的时候,如何找到对应的task_struct呢?



一般是从当前CPU的一个寄存器里面,通过函数current_thread_info得到在内核态里面的thread_info的地址,然后就可以通过指针找到task_struct了。


六、进程树


[IMG]


task_struct中有一系列指针是用来维护进程树的。



[IMG]


parent指向的是一个进程的原来的父进程,real_parent指向的是进程的当前的父进程,这两个值大多数情况下是一致的。


但是有一种情况下不一致,就是在一个进程被Debug的时候,这个时候GDB就变成了当前的父进程。


[IMG]
父进程有一个children指针指向子进程的列表,里面有两个指针,一个指头,一个指尾。


同一个层次的进程通过sibing链表串起来。


七、进程的资源管理


一个进程是一系列资源的集合,主要有哪些资源呢?


[IMG]
一个是files,指向这个进程打开的所有的文件,具体可参考Linux的虚拟文件系统VFS。

一个是fs,指向文件系统相关的信息,例如进程的当前目录等,也可参考上面的那篇文章。
一个是sighand,指向用于处理信号的signal handler
一个是mm,指向这个进程的内存。


八、fork创建子进程



[IMG]


通过调用系统调用fork可以创建另一个进程。


会在内核里面调用_do_fork
[IMG]


里面会调用
p = copy_process(clone_flags, stack_start, stack_size, child_tidptr, NULL, trace, tls, NUMA_NO_NODE);


[IMG]


里面有
p = dup_task_struct(current, node);
retval = copy_creds(p, clone_flags);
cgroup_fork(p);
retval = copy_files(clone_flags, p);
retval = copy_fs(clone_flags, p);
retval = copy_sighand(clone_flags, p);
retval = copy_signal(clone_flags, p);
retval = copy_mm(clone_flags, p);
retval = copy_namespaces(clone_flags, p);
retval = copy_io(clone_flags, p);
retval = copy_thread_tls(clone_flags, stack_start, stack_size, p, tls);
pid = alloc_pid(p->nsproxy->pid_ns_for_children);


子进程有独立的task_struct结构,有自己的PID,在fork的当下,代码段是和父进程是一样的,一般会被exec系列函数重新加载新的代码段,数据段和栈是新创建的,采取的copy on write的模式。



上面提到的四个数据结构,都是完全拷贝一份的。


九、pthread_create创建新线程


新的线程和原来的线程是共享进程空间的,因而调用__clone函数。


在内核中调用sys_clone函数,但是会设定以下的flag
CLONE_VM,则子线程和父线程共享虚拟内存
CLONE_FILES,共享files
CLONE_FS,共享fs
CLONE_SIGHAND,共享sighand。


[IMG]
互联网金融大洗牌,良币是时候驱逐劣币了! 高可用性的几个级别 市值蒸发三个亿,三全爆发“猪瘟”水饺,盈利还要不要底线? 春节前的你VS春节后的你 取消一个证!国家刚宣布!2月25日起,私对私、私对公20万元以上转账将严查!
好看吗?
总执行时间0.07401657104492188,文章查询时间0.047408342361450195,分类查询时间0.009793281555175781,其他脚本0.00027871131896972656,模板渲染0.016536235809326172