linux中创建进程是直接的,就是简单的一个fork调用,linux认为进程就是执行的一个任务,并没有和可执行文件联系起来,如果非要和可执行文件 联系的话就要涉及到另一个系统调用exec.linux这么实现取得了很大的灵活性,这个灵活性实际上也是继承unix的,因为unix就是这样实现进程的,进程在unix或者类unix比如linux系统中就是一个执行续,而不是别的什么特殊的东西,这使得在这些系统中很容易就实现了线程的概念,而且可 以用统一的管理系统去管理线程或者进程,所不同的仅仅是进程拥有另外一些东西而线程却没有,线程成了进程的完全子集,这在设计上是很重要的.相 反,windows内核虽然完全实现了线程,但是它实现的线程却和进程的概念是完全分离的,唯一的相同点就是都是nt执行体的"可执行"对象,统一于对象 管理器,继承了可执行对象的一切特性.这样windows实现的现代进程和线程的概念就相当松散,不利于统一管理,这完全体现在用户接口上,我们看一下 windows的进程创建接口;
BOOL CreateProcess
(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes。
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
这 里仅仅给出接口声明和简单的解释,更详细的请查阅MSDN,第一个参数是可执行模块的名称字符串,第二个是命令行,...就不多说了,看得晕吗?我是不喜 欢这种方式了,为什么进程一定要有可执行模块?去问微软吧!这也可能是微软的策略,故意让你进入他自己的开发模式,然后上瘾然后你就离不开微软了...; 再看一眼它的线程创建接口:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
    ); 
这个线程接口倒是比进程接口来的更直接,但是还是限制了很多东西,比如这回倒不必调用可执行模块了,但是为什么线程一定要有一个函数指针呢?
回归进程和线程的本意,进程是程序在计算机上的一次执行活动;线程是程序中一个单一的顺序控制流程。进程一定要有可执行模块吗?线程一定要有函数指针吗?都是不必的,可是提供给进程一 个可执行模块提供给线程一个函数指针会使得概念理解起来更容易,但是好处也仅仅如此。看看linux的方式吧,unix也同样。
   linux中的进程和线程接口一样,都是fork,并且没有参数,那怎么区分呢?linux提供了另一个系统调用接口clone,但是clone本质上也 是用的fork,就是多加了一个参数用来识别要创建的是一个线程。fork在内核中实现为sys_fork,clone的内核实现为sys_clone, 我们看一眼它们的形式:

asmlinkage int sys_fork(struct pt_regs regs)

{

return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);

}

asmlinkage int sys_clone(struct pt_regs regs)

{

unsigned long clone_flags;

unsigned long newsp;

int __user *parent_tidptr, *child_tidptr;

clone_flags = regs.ebx;

newsp = regs.ecx;

parent_tidptr = (int __user *)regs.edx;

child_tidptr = (int __user *)regs.edi;

if (!newsp)

newsp = regs.esp;

return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);

}

可 以看到二者都调用了do_fork,do_fork的代码就不分析了,这不是本文的主题,要注意的是do_fork的第一个参数是个标志,这个标志告诉内 核要创建的执行续是什么性质的,其中一个标志是CLONE_THREAD,就是要创建线程,而别的就是创建进程,当然标志是很丰富的,值得细细推敲。除了 标志没有任何限制,没有让用户提供什么别的东西,这其实是真正的进程/线程创建,试想有时候我仅仅想开辟一块内存然后让一个任务作为一个进程不被打扰得运 行,拥有自己的地址空间等等,而我没有关于这个任务的任何可执行文件。进程就是拥有独立的空间,是一个容器,而线程就是和别的同一进程的线程们共享该进程的空间和信号等等,至于说和可执行文件还有函数指针的联系是后来人们加上的,微软还真当成事儿了,当成规则标准了,这不是误人子弟吗?
那么linux要执行可执行文件该咋办呢?当然有办法了,不过要知道,linux认为一旦你执行了exec,你就是放弃了当前的进程地址空间而使用了新的地址空间来加载exec需要的可执行文件,这和有些文章说的地址空间蒸发不谋而合,但是不是蒸发了,而是被放弃了,仅仅是递减了该地址空间的引用计数而已,如果就一个task_struct使用了该mm_struct,那么它就被释放了,如果很多线程共享这个mm_struct,那么也就这个执行 exec的线程放弃了该mm_struct,对别的线程没有任何影响,可以看一下代码:

int do_execve(char * filename,

char __user *__user *argv,

char __user *__user *envp,

struct pt_regs * regs)

{

...

bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);

...

bprm->file = file;

bprm->filename = filename;

bprm->interp = filename;

bprm->mm = mm_alloc();  //bprm申请了一个mm_struct

...

retval = search_binary_handler(bprm,regs);

...

}

我们看到专门为一个可执行的二进制文件申请了一个地址空间mm_struct,这个地址空间将来要替换当前进程的地址空间,我们马上看到这一幕,在search_binary_handler 最终要调用elf的加载函数load_elf_binary,在该函数里实现了替换,调用了retval = flush_old_exec(bprm)我们看一下这个非常的retval = flush_old_exec(bprm);

int flush_old_exec(struct linux_binprm * bprm)

{

...

retval = exec_mmap(bprm->mm);  //这个函数最终实现了替换

...

set_task_comm(current, tcomm);

current->flags &= ~PF_RANDOMIZE;

flush_thread();

current->mm->task_size = TASK_SIZE;

...

current->self_exec_id++;

flush_signal_handlers(current, 0);

flush_old_files(current->files);

...

}

在exec_mmap中有几个重要的操作实现了替换,我们看一下:
tsk = current;
old_mm = current->mm;
mm_release(tsk, old_mm);
active_mm = tsk->active_mm;
tsk->mm = mm;
tsk->active_mm = mm;
activate_mm(active_mm, mm);
这几个就不用多说了,这里的mm_release就是所谓的蒸发,希望大家通过这个对地址空间的蒸发知其所以然。
最后说一下另一个系统调用vfork,vfork不实现写时复制,而是阻塞当前调用线程,其间和被阻塞的进程公用地址空间,只有到子进程调用exec或exit时才唤醒被阻塞线程,这是为何呢?因为当子进程执行exec时,它放弃了地址空间,所以原线程就又可以用了

fork,vfork以及exec的意义相关推荐

  1. fork vfork exit _exit (转)

    原文地址:http://hi.baidu.com/ikaruga11/blog/item/fb6d75725a8d8d148701b080.html APUE上的一个例子: example1 (for ...

  2. 【Linux进程、线程、任务调度】二 fork/vfork与写时拷贝 线程的本质 托孤 进程睡眠和等待队列

    学习交流加(可免费帮忙下载CSDN资源): 个人微信: liu1126137994 学习交流资源分享qq群1(已满): 962535112 学习交流资源分享qq群2(已满): 780902027 学习 ...

  3. 使用vfork、exec系列函数、wait/waited实现system函数的功能

    使用vfork.exec系列函数.wait/waited实现system函数的功能 #include <stdio.h> #include <string.h> #includ ...

  4. linux系统编程学习_(2)进程控制-- fork函数、exec函数族、回收子进程--孤儿进程僵尸进程、wait函数

    linux系统编程学习_(2)进程控制-- fork函数.exec函数族.回收子进程–孤儿进程僵尸进程.wait函数 进程控制 fork()函数 创建一个子进程. pid_t fork(void); ...

  5. linux中fork, source和exec的区别

    shell的命令可以分为内部命令和外部命令. 内部命令是由特殊的文件格式.def实现的,如cd,ls等.而外部命令是通过系统调用或独立程序实现的,如awk,sed. source和exec都是内部命令 ...

  6. 函数fork vfork

    一.函数fork fork函数原型: #include <unistd.h> pid_t fork(void); 二.程序清单 1. 测试代码: #include <unistd.h ...

  7. linux下gdb单步调试

    用 GDB调试程序 GDB 概述 ---- GDB 是 GNU开源组织发布的一个强大的 UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像 VC. BCB等 IDE的调试,但如果你是在 ...

  8. gdb 调试命令的使用及总结

    GDB: The GNU Project Debugger:http://www.gnu.org/software/gdb/documentation/ 参考:http://www.jianshu.c ...

  9. 07 - 进程创建大盘点

    ---- 整理自狄泰软件唐佐林老师课程 查看所有文章链接:(更新中)Linux系统编程训练营 - 目录 文章目录 1. 进程创建回顾 2. 再论进程创建 2.1 思考 2.2 vfork()深度分析 ...

最新文章

  1. python3 转码的函数_python基础3之文件操作、字符编码解码、函数介绍
  2. 【Android 高性能音频】hello-oboe 示例解析 ( Oboe 源代码依赖 | CMakeList.txt 构建脚本分析 | Oboe 源代码构建脚本分析 )
  3. bool 变量想为什么一般初始化为FALSE 比较好?
  4. C# Http方式下载文件到本地类改进版
  5. WinFormsChartSamples
  6. python之gunicorn的配置
  7. readhat7mysql_Redhat7.3安装MySQL8.0.22的详细教程(二进制安装)
  8. 顶隙计算公式_齿轮参数计算公式
  9. 彻底了解Windows XP操作系统登录类型
  10. VM虚拟机安装黑群晖教程
  11. [linux] grep -rn 当前目录搜索字符串
  12. 【算法】两矩形相交的判定
  13. 北航计算机专业怎么样考研好考不,计算机专业考研,北航和北邮各有什么优势...
  14. cta 音频测试_CTA入网认证一般测试哪些项目流程
  15. 仿微信/支付宝的自定义提现密码输入(二)
  16. z-index的使用及注意事项
  17. 新买的幻16笔记本不激活的情况下联网使用解决方案(双系统)
  18. 一文看懂Web3.0:元宇宙的基础设施,三大标签颠覆互联网
  19. OpenCV--014: 图像插值
  20. MATLAB的MEX文件编写和调试

热门文章

  1. 哪一刻你才发现青春结束了
  2. linux显卡驱动安全模式,win7在安全模式安装显卡驱动的详细教程
  3. 算法设计与分析: 5-14 独立钻石跳棋问题
  4. GitHub上最全的前端入门资源汇总 快如入门前端
  5. GD32F303调试小记(二)之SPI(软件SPI、硬件SPI、硬件SPI+DMA)
  6. oracle批量粘贴文本,ORACLE 快速批量导入文本数据到数据库(sqlldr工具)方法与分析...
  7. DellOptiPlex 5060台式机WinServer2012系统安装网卡驱动回顾
  8. 3.3 多路复用技术
  9. 阿里云产品推荐——网关
  10. 圣诞节品牌推广:5大海外网红营销案例分享