fork和exec
fork
pid_t fork(void);
- 它在调用进程(成为父进程)中返回一次,返回值为新派生进程(成为子进程)的进程ID号
- 在子进程中又返回一次,返回值为0.因此,返回值本身告知当前进程是子进程还是父进程
fork在子进程中返回0而不是父进程的ID的原因:
- 任何子进程只有一个父进程,而且子进程总是可以通过调用getppid取得父进程的ID
- 父进程可以有许多子进程,而且无法获得各个子进程的进程ID。如果父进程想要跟踪所有子进程的ID,那么它必须记录每次调用fork的返回值。
父进程中调用fork之前打开所有的描述字在fork返回之后由子进程分享。父进程调用accept之后调用fork。所接受的已连接的套接口随后就在父进程与子进程之间分享。通常情况下,子进程接着读和写这个套接口,父进程则关闭这个已连接套接口。
用法:
- 一个进程创建一个自身的拷贝,这样每个拷贝都可以在另一个拷贝执行其他任务的同时处理各自的某个操作。这是网络服务器的典型用法。
- 一个进程想要执行另一个程序。既然创建新进程的唯一方法为调用fork,该进程于是首先调用fork创建一个自身的拷贝,然后其中一个拷贝(通常为子进程)调用exec把自身替换成新的程序。这是诸如shell之类程序的典型用法。
- fork产生的子进程将继承父进程的信号掩码,但具有一个空的挂起信号集
exec
存放在硬盘上的可执行文件能够被UNIX执行的唯一方法是:由一个现有进程调用六个exec函数中的某一个
- exec把当前进程映像替换成新的进程文件,而且该新程序通常从main函数处开始执行
- 进程ID并不改变
- 我们称调用exec的进程为调用进程,称新执行的程序为新程序
#include <unistd.h> int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg, ..., char *const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execve(const char *path, char *const argv[], char *const envp[]);
六个exec函数的区别
- 待执行的程序文件是由文件名还是由路径名指定
- 新程序的参数是一一列出还是由一个指针数组来引用
- 把调用进程的环境传递给新程序还是给新程序指定新的环境
这些函数只在出错时才返回到调用者。否则,控制将传递给新程序的起始点,通常就是main函数。
这六个函数之间的关系如下图所示。一般来说,只有 execve 是内核中的系统调用,其他五个都是调用 execve 的库函数。

- 顶行三个函数把新程序的每个参数字符串指定成exec的一个独立参数,并以一个空指针结束可变数量的这些参数。底行三个函数都有一个作为exec参数的argv数组,其中含有指向新程序各个参数字符串的所有指针。既然没有指定参数字符串的数目,这个argv数组必须含有一个用于指定其末尾的空指针。
- 左列两个函数指定一个filename参数。exec将使用当前的PATH环境变量把该文件名参数转换为一个路径名。然而如果这两个函数的filename参数中不论何处含有一个斜杠(/),PAHT变量就不再使用。右两列四个函数指定一个全限定的pathname参数。
- 左两列四个函数不显式指定一个环境指针。相反,他们使用外部变量environ的当前值来构造一个传递给新程序的环境清单。右列两个函数显式指定一个环境清单,其envp指针数组必须以一个空指针结束。
//execv int childpid; int i; ) { //child process char * execv_str[] = {"echo", "executed by execv",NULL}; ) { perror("error on exec"); exit(); } } else { //parent process wait(&childpid); printf("execv done\n\n"); } //execvp ) { //child process char * execvp_str[] = {"echo", "executed by execvp",">>", "~/abc.txt",NULL}; ) { perror("error on exec"); exit(); } } else { //parent process wait(&childpid); printf("execvp done\n\n"); } //execve ) { //child process char * execve_str[] = {"env",NULL}; char * env[] = {"PATH=/tmp", "USER=lei", "STATUS=testing", NULL}; ) { perror("error on exec"); exit(); } } else { //parent process wait(&childpid); printf("execve done\n\n"); } //execl ) { //child process ) { perror("error on exec"); exit(); } } else { //parent process wait(&childpid); printf("execv done\n\n"); } //execlp ) { //child process ) { perror("error on exec"); exit(); } } else { //parent process wait(&childpid); printf("execv done\n\n"); } //execle ) { //child process char * env[] = {"PATH=/home/gateman", "USER=lei", "STATUS=testing", NULL}; ){ perror("error on exec"); exit(); } } else { //parent process wait(&childpid); printf("execle done\n\n"); }
fork和exec的更多相关文章
- 【转】Linux下Fork与Exec使用
Linux下Fork与Exec使用 转自 Linux下Fork与Exec使用 一.引言 对于没有接触过Unix/Linux操作系统的人来说,fork是最难理解的概念之一:它执行一次却返回两个值.for ...
- Linux下Fork与Exec使用
Linux下Fork与Exec使用 一.引言 对于没有接触过Unix/Linux操作系统的人来说,fork是最难理解的概念之一:它执行一次却返回两个值.fork函数是Unix系统最杰出的成就之一, ...
- linux进程之fork 和 exec函数
---恢复内容开始--- fork函数 该函数是unix中派生新进程的唯一方法. #include <unistd.h> pid_t fork(void); 返回: (调用它一次, 它 ...
- linux c语言 fork() 和 exec 函数的简介和用法
linux c语言 fork() 和 exec 函数的简介和用法 假如我们在编写1个c程序时想调用1个shell脚本或者执行1段 bash shell命令, 应该如何实现呢? 其实在<std ...
- Linux下Fork与Exec
一.引言 对于没有接触过Unix/Linux操作系统的人来说,fork是最难理解的概念之一:它执行一次却返回两个值.fork函数是Unix系统最杰出的成就之一,它是七十年代UNIX早期的开发者经过长期 ...
- fork 和 exec
https://blog.csdn.net/disadministrator/article/details/39347333 进程创建方法:fork.exec.clone,父进程等待子进程结束是用w ...
- fork、exec 和 exit 对 IPC 对象的影响
GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区: https://bbs.huaweicloud.com/ ...
- Linux fork()、exec() Hook Risk、Design-Principle In Multi-Threadeed Program
目录 . Linux exec指令执行监控Hook方案 . 在"Multi-Threadeed Program"环境中调用fork存在的风险 . Fork When Multi-T ...
- fork和exec一起使用
先预览一下工程的目录树: 实现的功能:master进程启动slave进程. 看看Makefile内容: all: master.out slave.out master.out: master.cpp ...
- fork和exec函数
#include<unistd.h> pid_t fork(void); 返回:在子进程中为0,在父进程中为子进程IO,若出错则为- fork最困难之处在于调用它一次,它却返回两次.它在调 ...
随机推荐
- Mysql找回丢失密码
(先进入root权限):# /etc/init.d/mysql stop# mysqld_safe --user=mysql --skip-grant-tables --skip-networking ...
- [HAOI2006]l旅行
这道题...一眼看出一个暴力思虑...那就是按照生成树... 排完序之后从当前边开始向后做生成树... 统计一下答案就好了... 结果...这就是正解...QVQ...smg...我去... 呆码: ...
- 玩转X-CTR100 l STM32F4 l DSP指令集性能测试
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器 DSP库的 ...
- Eclipse几点常用设置+个人喜好
1.代码自动提示 在我们忘记方法名或者想偷懒时,代码自动提示很管用.不过Eclipse默认是输入"."后才会出现包或类成员的提示,也就意味着我们必须先输入一个完整的类名,提示才能出 ...
- 百度地图API示例:鼠标绘制点线面 控件修改
需求 :在使用地图API时,绘制工具栏控件想自己选择哪些要,哪些不要. 可以查看相应的类:官网地址: http://api.map.baidu.com/library/DrawingManager/1 ...
- PMS5003ST传感器
5003ST传感器已经收到,准备开始DIY PM2.5检测仪 一款可以同时监测空气中颗粒物浓度.甲醛浓度及温湿度的三 合一传感器.其中颗粒物浓度的监测基于激光散射原理,可连续采集并计算单位 ...
- shell日常实战防dos攻击
根据web日志或者或者网络连接数,监控当某个IP并发连接数或者短时内PV达到100,即调用防火墙命令封掉对应的IP,监控频率每隔3分钟.防火墙命令为:iptables -I INPUT -s 10.0 ...
- 初玩OpenWRT之编译TP-Link WR841N V8固件
0x00 安装依赖 安装git以下载OpenWrt源码.安装编译工具以进行交叉编译: sudo apt-get update sudo apt-get install build-essential ...
- 由于php环境时间与北京时间相差7个小时
故在设置当前时间时候需要加上 date_default_timezone_set('prc'); 或者 在php.ini里面设置date.timezone=prc
- python socket 编程之三:长连接、短连接以及心跳(转药师Aric的文章)
长连接:开启一个socket连接,收发完数据后,不立刻关闭连接,可以多次收发数据包. 短连接:开启一个socket连接,收发完数据后,立刻关闭连接. 心跳:长连接在没有数据通信时,定时发送数据包(心跳 ...