帝国cms做企业网站大连制作网站公司
news/
2025/10/5 10:23:13/
文章来源:
帝国cms做企业网站,大连制作网站公司,it培训套路,做海报图片去哪个网站找 知乎上文讲了《Linux进程在内核眼中是什么样子的#xff1f;》#xff0c;可以理解内核关于进程线程的所有管理就通过一个结构体 —— task_struct。知道了内核眼中进程的描述#xff0c;本文通过三个例子站在用户态看下进程线程是如何创建的#xff0c;不同的创建方式又有哪些… 上文讲了《Linux进程在内核眼中是什么样子的》可以理解内核关于进程线程的所有管理就通过一个结构体 —— task_struct。知道了内核眼中进程的描述本文通过三个例子站在用户态看下进程线程是如何创建的不同的创建方式又有哪些优劣fork例子先看一个例子#include#include#includeint main() { pid_t pid; int cnt 0; pid fork(); if(pid0) printf(error in fork!\n); else if(pid 0) { cnt; printf(cnt%d\n,cnt); printf(I am the child process,ID is %d\n,getpid()); } else { cnt; printf(cnt%d\n,cnt); printf(I am the parent process,ID is %d\n,getpid()); } return 0; }运行结果为cnt1I am the parent process,ID is 15247cnt1I am the child process,ID is 15248注意第二个cnt并不是2为什么会这个结果呢因为子进程是父进程的副本它将获得父进程数据空间、堆、栈等资源的副本。这意味着父子进程间不共享这些存储空间。内核将复制父进程的地址空间内容给子进程因此子进程有了独立的地址空间。由于在复制时复制了父进程的堆栈段所以两个进程都停留在fork函数中等待返回。因此fork函数会返回两次一次是在父进程中返回另一次是在子进程中返回这两次的返回值是不一样的。调用fork之后数据、堆栈有两份但是代码段仍然为一份这个代码段是两个进程的共享代码段都从fork函数中返回。当父子进程有一个想要修改数据或者堆栈时两个进程真正分裂。fork有两个特点“调用一次返回两次”在父进程中调用一次在父进程和子进程中各返回一次。所有由父进程打开的描述符都被复制到子进程中。父、子进程中相同编号的文件描述符在内核中指向同一个file结构体也就是说file结构体的引用计数要增加。vfork例子把上面程序中的fork改成vfork运行结果是什么样子的呢cnt1I am the child process,ID is 15385cnt-486109114I am the parent process,ID is 15384a.out: cxa_atexit.c:100: __new_exitfn: Assertion l ! NULL failed.Aborted (core dumped)咦为什么会有段错误这是因为没有调用exec函数vfork()保证子进程先运行在它调用exec或exit之后父进程才可能被调度运行。我们把上面的程序修改如下#include#include#includeint main() { pid_t pid; int cnt 0; pid vfork(); if(pid0) printf(error in fork!\n); else if(pid 0) { cnt; printf(cnt%d\n,cnt); printf(I am the child process,ID is %d\n,getpid()); _exit(0); } else { cnt; printf(cnt%d\n,cnt); printf(I am the parent process,ID is %d\n,getpid()); } return 0; }运行结果如下cnt1I am the child process,ID is 15524cnt2I am the parent process,ID is 15523可见成功执行了并且cnt是2。因为调用了exec使得子进程退出父进程执行这样else 后的语句就会被父进程执行又因在子进程调用exec或exit之前与父进程数据是共享的, 所以子进程退出后把父进程的数据段count改成1 了子进程退出后父进程又执行最终就将cnt变成了2。fork 和 vfork的一些思考根据上面的例子我们知道 fork 和 vfork 各有优劣可以用下图大概描述。图片来自网络fork 要多拷贝一次内存vfork 用起来又麻烦而且有风险讲真并不鼓励用 vfork。那么有没有办法对 fork 做个优化答案是肯定的。目前内核对 fork 做了写时拷贝(COW)的优化。也就是说对于fork后并不是立马拷贝内存而是只有你在需要改变的时候才会从父进程中拷贝到子进程中这样fork 后立马执行 exec 的成本就非常小了。clone 创建线程现在我们知道了创建进程有两种方式forkvfork。那么创建线程呢首先得知道什么是进程什么是线程。有句名言 “进程是资源管理的最小单位线程是程序执行的最小单位。” 在操作系统设计上从进程演化出线程最主要的目的就是减小多进程上下文切换开销。因此进程之间共享代码段文件描述符信号处理全局变量等的话就称为线程如果不共享就是我们所说的进程。线程的创建接口是用 clone或者经常用的 pthread_create。进程线程创建总图我们先站在上帝视角以一张图来看下进程线程创建的大体框架具体的实现下文见。添加极客助手微信加入技术交流群长按扫码关注公众号
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/928122.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!