创建进程的函数

clone()、fork()、vfork()都是Linux的系统调用。

进程一般由代码段、数据段和PCB进程控制块组成。

fork 创造的子进程复制了父亲进程的资源,包括内存的内容task_struct内容,新旧进程使用同一代码段,复制数据段和堆栈段,这里的复制采用了注明的copy_on_write技术,即一旦子进程开始运行,则新旧进程的地址空间已经分开,两者运行独立。

优点是子进程的执行独立于父进程,具有良好的并发性。

缺点是两者的通信需要专门的通信机制,如pipe、fifo和system V等。

其实在复制过程中,子进程复制了父进程的task_struct,系统堆栈空间和页面表,在子进程运行前,两者指向同一页面。而当子进程改变了父进程的变量时候,会通过copy_on_write的手 段为所涉及的页面建立一个新的副本。因此fork效率并不低。

vfork函数创建的子进程完全运行在父进程的地址空间上,子进程对虚拟地址空间任何数据的修改都为父进程所见。这与fork是完全不同的,fork进程是独立的空间。另外一点不同的是vfork创建的子进程后,父进程会被阻塞,直到子进程执行exec()和exit()。

当创建子进程的目的仅仅是为了调用exec()执行另一个程序时,子进程不会对父进程的地址空间又任何引用。因此,此时对地址空间的复制是多余的,通过vfork可以减少不必要的开销。

系统调用fork()和vfork()是无参数的,而clone()则带有参数。fork()是全部复制,vfork()是共享内存,而clone()是则可以将父进程资源有选择地复制给子进程,而没有复制的数据结构则通过指针的复制让子进程共享,具体要复制哪些资源给子进程,由参数列表中的clone_flags来决定。另外,clone()返回的是子进程的pid。

轻量级进程由clone()函数创建。clone函数功能强大,带了众多参数,因此由他创建的进程要比前面2种方法要复杂。clone可以让你有选择性的继承父进程的资源,你可以选择想vfork一样和 父进程共享一个虚存空间,从而使创造的是线程,你也可以不和父进程共享,你甚至可以选择创造出来的进程和父进程不再是父子关系,而是兄弟关系

int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);

这里fn是函数指针,我们知道进程的4要素,这个就是指向程序的指针,就是所谓的“剧本", child_stack明显是为子进程分配系统堆栈空 间(在linux下系统堆栈空间是2页面,就是8K的内存,其中在这块内存中,低地址上放入了值,这个值就是进程控制块task_struct的 值),flags就是标志用来描述你需要从父进程继承那些资源, arg就是传给子进程的参数)。

系统调用服务例程sys_clone, sys_fork, sys_vfork三者最终都是调用do_fork函数完成.

do_fork的参数与clone系统调用的参数类似, 不过多了一个regs(内核栈保存的用户模式寄存器). 实际上其他的参数也都是用regs取的

  • clone:

    • clone的API外衣, 把fn, arg压入用户栈中, 然后引发系统调用. 返回用户模式后下一条指令就是fn.
    • sysclone: parent_tidptr, child_tidptr都传到了 do_fork的参数中
    • sysclone: 检查是否有新的栈, 如果没有就用父进程的栈 (开始地址就是regs.esp)
  • fork, vfork:
    • 服务例程就是直接调用do_fork, 不过参数稍加修改
    • clone_flags:
      • sys_fork: SIGCHLD|0;
      • sys_vfork: SIGCHLD| (clone_vfork | clone_vm)
    • 用户栈: 都是父进程的栈.
    • parent_tidptr, child_ctidptr都是NULL.

以上有内容引用来自http://www.51develop.net/forum.php?mod=viewthread&tid=8963

copy_process()创建进程描述符以及子进程执行所需要的所有其他数据结构。它的参数与do_fork()参数相同,外加子进程的PID。

时间: 2024-11-12 11:34:24

创建进程的函数的相关文章

【归纳总结】Unix/linux下的进程管理(二):创建进程的函数及其应用、对比

创建进程的函数fork().vfork()和execl() 本次内容主要介绍Unix/linux下2个创建进程的函数fork和vfork以及它们的差别. 1.fork函数 (1)函数的格式 #include <unistd.h> pid_t fork(void); 函数功能: 主要用于以复制正在运行进程的方式来创建新的进程,其中新进程叫做子进程,正在运行的进程叫做父进程. 返回值: 函数调用成功时,父进程返回子进程的PID,子进程返回0,函数调用出错时,父进程返回-1,子进程没有被创建. 注意

关于Windows创建进程的过程

之前有听到别人的面试题是问系统创建进程的具体过程是什么,首先想到的是CreateProcess,但是对于具体过程却不是很清楚,今天整理一下. 从操作系统的角度来说 创建进程步骤:        1.申请进程块              2.为进程分配内存资源        3.初始化进程块        4.将进程块链入就绪队列 课本上的知识... 从CreateProcess的具体流程来说: CreateProcess它首先创建一个执行体进程对象,即EPROCESS 对象,然后创建一个初始线程

linux进程编程:子进程创建及执行函数简介

子进程创建及执行函数有三个: (1)fork();(2)exec();(3)system();    下面分别做详细介绍.(1)fork()    函数定义:    pid_t fork();    函数说明:    linux下进程在内存中由三部分数据组成:代码段.数据段.堆栈段.在一个进程中,调用fork函数,可以创建.启动一个新进程.新进程与父进程共享代码段,复制父进程的数据段和堆栈段.创建成功后,fork()会向两个进程都有返回值.向父进程的返回值为子进程的进行号,向子进程的返回值为0.

创建进程时注入DLL

#include "stdafx.h" #include <Windows.h> // 函数声明 typedef BOOL (WINAPI* Proc_CreateProcessW)(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInherit

Delphi 使用CreateProcess创建进程并弹出进程PID值

var  ExeName:PChar;  StartupInfo:TStartupInfo;  ProcessInfo:TProcessInformation;begin  FillChar(ProcessInfo,sizeof(TProcessInformation),0);  FillChar(StartupInfo,Sizeof(TStartupInfo),0);  StartupInfo.cb:=Sizeof(TStartupInfo);  StartupInfo.dwFlags:=ST

Java 多线程详解(二)------如何创建进程和线程

Java 多线程详解(一)------概念的引入:http://www.cnblogs.com/ysocean/p/6882988.html 在上一篇博客中,我们已经介绍了并发和并行的区别,以及进程和线程的理解,那么在Java 中如何创建进程和线程呢? 1.在 Windows 操作系统中创建进程 在 windows 操作系统中,我们创建一个进程通常就是打开某个应用软件,这便在电脑中创建了一个进程.更原始一点的,我们在命令提示符中来做(我们以打开记事本这个进程为例): 第一步:windows+R,

linux创建进程fork的方法步骤

fork创建进程 函数原型如下 #include// 必须引入头文件,使用fork函数的时候,必须包含这个头文件,否则,系统找不到fork函数 pid_t fork(void); //void代表没有任何形式参数 父进程与子进程 1.掌握概念,什么是父进程,什么是子进程 除了0号进程(系统创建的)之外,linux系统中都是由其他进程创建的.创建新进程的进程,即调用fork函数的进程为父进程,新建的进程为子进程. 2.fork函数不需要任何参数,对于返回值有三种情况 1)对于父进程,fork函数返

Linux创建子进程的函数说明

1. fork函数,创建一个子进程 pid_t fork(void); //pid_t就是一个整形类型 返回值: 成功的情况下,父进程返回子进程的id(非负整数),子进程返回0: 失败的情况,父进程返回-1,创建子进程失败,也就是没有创建子进程. 举例说明: int main(int argc,char* argv[]) { pid_t pid; pid = fork(); //创建一个子进程,从这段代码开始(包括这段代码)往后,就有两个进程在执行了, //但是,哪个进程先执行不确定,看哪个进程

Windows平台下的session0创建进程的问题与解决办法

很多博客都有记载如何在session0下创建进程的办法,也就是使用CreateProcessAsUser.但是这个要求服务的进程有SE_INCREASE_QUOTA_NAME和SE_ASSIGNPRIMARYTOKEN_NAME权限.如果设置的登录用户是LocalServer的话,是默认有以上两个权限.但是如果是自己创建的账户,那么是不具有SE_ASSIGNPRIMARYTOKEN_NAME的权限. 查看用户的权限可以通过gpedit.msc工具中,在"计算机配置"-- "W