通过调用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 内存的分布问题

    php运行,内存分为5个区域, 1.基本数据类型--->栈区 2.符合数据类型-->堆区 对象实例在堆区,对象名字在栈区(指向此对象实例的变量)

  2. mybatis中几种typeHandler的定义使用

    1.存储到数据库, 将LONG数组转换成字符串;从数据库获取数据, 将字符串转为LONG数组 package com.winturn.utils.handler; import java.sql.Ca ...

  3. webrtc学习———记录一

    最近导师让研究一下webrtc,希望将来用到我们的ICT2系统中. 但是从来没有过做web的基础,无论前端还是后端,html.js全都从头学起.html还好说,没有太过复杂的东西. js就有点难度了, ...

  4. 用Markdown优雅的渲染我们的网页

    认识 Markdown Markdown 是一种用来写作的轻量级「标记语言」,它用简洁的语法代替排版,而不像一般我们用的字处理软件 Word 或 Pages 有大量的排版.字体设置.它使我们专心于码字 ...

  5. ASP.NET 相关小知识

    后台修改前台html控件属性 添加 runat=server ,后台获取// 客户端隐藏 a.Attributes[ "style "] = "display:none ...

  6. 国内最简单的短视频SDK

    最近阿里百川和趣拍一起合作推出了一个短视频SDK.之前很多厂商可能都是用的Vitamio的短视频SDK.之后我考察过,也做过一些调查,发现Vitamio真的奇贵无比,屌丝公司根本用不起,阿里和趣拍这下 ...

  7. Angularjs总结(三)摸态框的使用

    静态页面: <input class="btn btnStyle " value="提 取" type="button" ng-cli ...

  8. CorAnimation7-高效绘图、图像IO以及图层性能

    高效绘图 软件绘图 术语绘图通常在Core Animation的上下文中指代软件绘图(意即:不由GPU协助的绘图).在iOS中,软件绘图通常是由Core Graphics框架完成来完成.但是,在一些必 ...

  9. 关于Java的一道内存的题目

    import java.util.Arrays; import java.util.EmptyStackException; public class MyStack<T> { priva ...

  10. 关于正则表达式的转义 PHP

    如正则的函数 preg_replace($patern, $replacement, $content) 等等 其中如果 $content 中要替换 \ 成 /,必须在 $patern中写成 \\\\ ...