⟅UNIX网络编程⟆⦔fork、exec函数

说在前面

数据类型说明

数据类型说明头文件
pid_t一般为int,见这里<unistd.h>

fork

fork(包括各种变体)是Unix中派生新进程的唯一方法。

  • 定义

    #include <unistd.h>
    pid_t fork(void);
    
    返回值:
    • 调用该函数一次,返回两次
    • 父进程(调用fork的进程)中,返回值为子进程(新派生进程)的进程ID;在子进程中,返回值为0。返回值本身可以告知当前进程是子进程还是父进程。
    • fork在子进程中返回0而不是父进程ID(即父进程返回0,子进程返回父进程ID)的原因:任何子进程只有一个父进程,而且子进程可以通过getppid函数获取父进程ID。父进程可以拥有许多子进程,但是却无法获取各个子进程ID。
  • 其他说明

    父进程调用fork之前打开的所有描述符(fd)在fork之后由子进程共享。网络服务器利用了这个特性:父进程调用accept后调用fork,所接受的已连接套接字随后就在父进程与子进程之间共享;通常,子进程继续读写该已连接套接字,父进程则关闭该已连接套接字(套接字描述符引用计数-1)
  • 典型用法

    • 一个进程创建一个自身的副本。每个副本都可以在另一个副本执行其他任务时处理各自的任务。这是网络服务器的典型用法。
    • 一个进程想要执行另一个程序。首先调用fork创建一个自身的副本,然后其中一个副本(通常为子进程)调用exec把自身替换为新的程序。这时诸如shell(例如运行./client.out)之类程序的典型用法。

exec

放在硬盘上的可执行程序文件能被Unix执行的唯一方法:由一个现有进程调用六个exec函数中的某一个。 exec将当前进程映像替换为新的程序文件,而且该新程序通常从main函数开始执行,该进程ID不变。(调用exec的进程被称为调用进程;新执行的程序被称为新程序。)

  • 定义

    #include <unistd.h>
    extern char **environ;
    
    int execl(const char *pathname, const char *arg, ...
                        /* (char  *) NULL */);
                        
    int execv(const char *pathname, char *const argv[]);
    
    int execle(const char *pathname, const char *arg, ...
                           /*, (char *) NULL, char * const envp[] */);
    
    int execvpe(const char *file, char *const argv[], char *const envp[]);
                           
    int execlp(const char *file, const char *arg, ...
                           /* (char  *) NULL */);
    
    int execvp(const char *file, char *const argv[]);
    
    // 注:在linux manual page中,上述六个函数被放在同一个条目中进行说明;
    // 它们在内核中调用execve
    // (The functions described in this manual page are front-ends for execve(2).)
    
    int execve(const char *pathname, char *const argv[], char *const envp[]);
    

    参数说明:

    • 这些函数之间的区别在于:
    1. 待执行的程序文件是由文件名(file)还是路径名(pathname)指定;
    2. 新程序的参数是一一列出还是由一个指针数组来引用;
    3. 把调用进程的环境传递给新进程还是给新程序指定环境。
    • 对于函数名中的l、p、e、v
      说明
      largument list,使用参数列表
      p使用环境变量PATH+文件名,若文件名中有斜杠‘/’,那么不添加PATH
      eenvironment,使用envp指定新的环境
      v参数使用指针数组(*const argv[],必须含有表示结尾的空指针)指定

    返回值:

    • 这些函数仅在出错时返回给调用进程;否则,控制(?)将被传递给新程序的起点,通常是main函数。
  • 其他说明

    • 上面三个函数(函数名均包含 l l l)把新程序的每个参数字符串均指定为exec的一个独立参数,并以一个空指针(即0)结束可变数量的参数列表。
      在这里插入图片描述
    • 下面四个函数(函数名均包含v)都有一个作为参数的argv数组,其中含有指向新程序各个参数字符串的所有指针。该数组必须包含一个表示结尾的空指针。
    • 左列两个函数(函数名均包含p)指定一个file参数。exec将环境变量PATH把文件名转换为路径名。但是一旦file中含有斜杠‘/’,就不再使用PATH。而右边五个函数(函数名均含p)则使用pathname作为参数。
    • 左两列四个函数(函数名均含e)不显示指定一个环境指针。它们使用外部环境变量environ的当前值(即fork后的进程的environ)来构造一个传递给新程序的环境列表。最右三个函数(函数名均包含v)显示指定环境列表,其中envp必须以空指针结束。

    进程在调用exec之前打开的描述符通常跨exec继续保持打开。但是该默认行为可以通过fcntl设置FD_CLOEXEC。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值