通过调用fork和exec函数都能创建新的进程,但两者有着本质的区别:fork函数拷贝了父进程的内存映像,而exec函数用用新的映像来覆盖调用进程的进程映像的功能。

一  fork函数

    #include <unistd.h>

    pid_t fork(void);    //创建子进程成功时,向子进程返回0,并将子进程的进程ID返回给父进程

               //创建失败时,返回-1,并将errno设置为EAGAIN

    返回值是允许父进程和子进程区别自己并执行不同代码的关键特征。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h> int main(void){
pid_t childpid;                     //子进程的ID
childpid=fork();                    //创建子进程
if(childpid==-){                                 //创建子进程失败
perror("Failed to fork");
return ;
}
if(childpid==){                                  //创建子进程成功
printf("I am child %ld\n",(long)getpid());      //打印子进程的ID
}
else{
printf("I am parent %ld\n",(long)getpid());     //打印父进程的ID
}
}

二 exec函数

  有六种不同形式的exec函数,如下:

#include <unistd.h>

int execl(const char *path,                      //进程映像文件的路径名,可以是全限定路径名,也可以是相对于当前目录的路径名
      const char *arg,...);               int execle(const char *path,const char *arg,...,char *const envp[]);     //最后一个参数必须以空指针(NULL)作结束
int execlp(const char *file,const char *arg,...);
int execv(const char *path,
      char *const argv[]);        //参数数组,用来存放指向你的字符串参数的指针数组
int execve(const char *path,char *const argv[],char *const envp[]);
int execvp(const char *file,char *const argv[]);

  execv开头的函数是把参数以"char *argv[]"这样的形式传递命令行参数。而execl开头的函数采用了我们更容易习惯的方式,把参数一个一个列出来,然后以一个NULL

表示结束,也可以写成(char *)0。

  如果创建子进程不成功,所有的exec函数都返回-1,并设置errno,以下是errno的类型和原因。

  E2BIG:新进程的参数表和环境表长度以系统所允许的ARG_MAX字节的限制要长

  EACCES:对新进程路径前缀中目录的搜寻权限被否定,新进程映像文件的执行权限被否定,或者新进程映像文件不是正常的文件,且不能被执行

  EINVAL:新进程映像文件有恰当的权限,且以可识别可执行的二进制格式出现

  ELOOP:在对参数path或file进行解析时存在循环

  ENAMETOOLONG:path或file的长度超出了PATH_MAX的范围,或者路径名组件比NAME_MAX要长

  ENOENT:path或file组件命名的不是一个现存的文件,或者path或file为空字符串

  ENOEXEC:映像文件有恰当的访问权限,但它的格式不可识别(不适用于execlp或execvp)

  ENOTDIR:映像文件路径前缀的组件不是一个目录

     int main(int argc,char *argv[],char *envp[])
{
char *arg[]={"ls","-a",NULL};
if(fork()==)
{
printf("execl...........\n");
if(execl("/bin/ls","ls","-a",NULL)<)
{
fprintf(stderr,"execl failed:%s",strerror(errno));
return -;
}
}
if(fork()==)
{
printf("execv...........\n");
if(execv("/bin/ls",arg)<)
{
fprintf(stderr,"execl failed:%s\n",strerror(errno));
return -;
}
}
if(fork()==)
{
printf("execlp...........\n");
if(execlp("ls","ls","-a",NULL)<)
{
fprintf(stderr,"execl failed:%s",strerror(errno));
return -;
}
}
if(fork()==)
{
printf("execvp...........\n");
if(execvp("ls",arg)<)
{
fprintf(stderr,"execl failed:%s\n",strerror(errno));
return -;
}
}
if(fork()==)
{
printf("execle...........\n");
if(execle("/bin/ls","ls","-a",NULL,envp)<)
{
fprintf(stderr,"execl failed:%s",strerror(errno));
return -;
}
}
if(fork()==)
{
printf("execve...........\n");
if(execve("/bin/ls",arg,envp)<)
{
fprintf(stderr,"execl failed:%s\n",strerror(errno));
return -;
}
}      return ;
}

Linux学习笔记12——Unix中的进程的更多相关文章

  1. Linux学习笔记12—磁盘管理

    一.查看磁盘或目录的容量 1.  df命令 作用:查看已挂载磁盘的总容量.使用容量.剩余容量等,可以不加任何参数,默认是按k为单位显示的 参数: -I : 查看inodes使用状况 -h: 使用合适的 ...

  2. Linux学习笔记(9)-守护进程

    明天学这个!! ---------------------------------------------------------- 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终 ...

  3. Hadoop学习笔记—12.MapReduce中的常见算法

    一.MapReduce中有哪些常见算法 (1)经典之王:单词计数 这个是MapReduce的经典案例,经典的不能再经典了! (2)数据去重 "数据去重"主要是为了掌握和利用并行化思 ...

  4. Linux学习笔记:ftp中binary二进制与ascii传输模式的区别

    在使用ftp传输文件时,常添加上一句: binary  -- 使用二进制模式传输文件 遂查资料,如下所获. FTP可用多种格式传输文件,通常由系统决定,大多数Linux/UNIX系统只有两种模式:文本 ...

  5. Linux学习笔记--ps命令(显示当前进程的命令)

    ps:英文名process,进程的意思. 1. 命令格式: ps [选项] 2. 经常使用选项: "ps -a" 显示一个终端的全部进程.除了会话引线 "ps -e&qu ...

  6. Linux学习笔记1-在CentOS 7中安装配置JDK8

    说明: 参考博客:http://blog.csdn.net/czmchen/article/details/41047187系统环境:CentOS 7安装方式:rpm安装JDK地址:http://ww ...

  7. linux学习笔记-12.输入输出重定向及管道

    1.新建一个文件 touch a.txt> b.txt 2.错误重定向:2> find /etc -name zhaoxing.txt 2> error.txt 3.将正确或错误的信 ...

  8. OpenCV学习笔记(12)——OpenCV中的轮廓

    什么是轮廓 找轮廓.绘制轮廓等 1.什么是轮廓 轮廓可看做将连续的点(连着边界)连在一起的曲线,具有相同的颜色和灰度.轮廓在形态分析和物体的检测和识别中很有用. 为了更加准确,要使用二值化图像.在寻找 ...

  9. Linux学习笔记之系统中的分区和文件系统

    转自 http://blog.csdn.net/hanxuehen/article/details/8229472

随机推荐

  1. PHP 正则通配符

    $a = preg_match('/ph+p/','aaaphpbbbp'); +的前导就是h $a = preg_match('/ph+p/','aaaphhhhhhhhhhpbbbp'); //第 ...

  2. Jquery Datatables(三)

    最近在项目中又使用Datatables的一个有趣功能,官网列子如下图: 点击“+”,展开列表,再次点击收缩. 官网的列子点击展开后的数据也是原来行中的数据,这边有了一个想法是否可以利用Ajax去动态加 ...

  3. RelativeLayout相对布局 安卓布局技巧

    http://blog.csdn.net/nieweiking/article/details/38417317 RelativeLayout相对布局 相对布局 RelativeLayout 允许子元 ...

  4. 解决 TortoiseGit 诡异的 Bad file number 问题

    http://blog.csdn.net/renfufei/article/details/41648061 问题描述 昨天,以及今天(2014-11-29),使用 TortoiseGit 时碰到了一 ...

  5. Java写一个简单学生管理系统

    其实作为一名Java的程序猿,无论你是初学也好,大神也罢,学生管理系统一直都是一个非常好的例子,初学者主要是用数组.List等等来写出一个简易的学生管理系统,二.牛逼一点的大神则用数据库+swing来 ...

  6. SQL Server 表字段值转列名 示例

    前几天,同事问我怎样把字段值转换成字段列,就写了一个最简单的Demo分享一下. 代码如下: -- 创建测试表以及添加测试数据create table #temp(a money,b varchar(1 ...

  7. jQuery 遍历祖先

    祖先是父.祖父或曾祖父等等. 通过 jQuery,您能够向上遍历 DOM 树,以查找元素的祖先. 向上遍历 DOM 树 这些 jQuery 方法很有用,它们用于向上遍历 DOM 树: parent() ...

  8. C# json与对象之间的相互转换

    1. 添加命名空间 using System.Runtime.Serialization.Json; 2. WriteObject方法 // 从一个对象信息生成Json串 public static ...

  9. java_反射_及其简单应用(2016-11-16)

    话不多说直接上代码 接口: package bean; /** * user接口 */ public interface User { public String getName(); public ...

  10. Codevs 4768 跳石头 NOIP2015 DAY2 T1

    4768 跳石头 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 传送门 题目描述 Description 一年一度的"跳石头"比赛又要开始了! ...