通过调用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. PGsql解决时差24H

    SELECT sa_ed_time, sa_st_time, case when sa_ed_time > sa_st_time then extract(EPOCH FROM (sa_ed_t ...

  2. 第二部分 Nhibernate中的类型

    NHibernate类型..net类型.数据库字段类型映射关系 因为NHibernate类型和c#数据类型是对应的,所以也分为值类型和引用类型,另外还有几个特殊的类,我们分别介绍: -- 值类型 | ...

  3. 从source folder 下将其所有子文件夹的*.* 文件拷贝到 target folder (不拷贝文件夹名仅拷贝文件)

    因本人较懒,一直认为电脑能做的就让电脑来做,所以写下这个批处理的小脚本方便工作. 场景:碰到要拷贝一个文件夹(source folder)下的多个子文件夹(sub-folder)的文件到指定文件夹下( ...

  4. SQL Server2008 附加数据库失败 错误代码5120

    由于目录权限不够导致 ,解决办法:将文件所在的文件夹增加everyone 并且赋予完全控制权限问题解决

  5. 使用DataList 分页方法

    什么是DataList我想应该不需要解释了,接下来分享本人在项目里使用到的通过DataList进行分页展示方法. 首先在ASPX页面添加一个DataList(后面都简称DL)控件,示例代码如下: &l ...

  6. Unix时间戳 和 NSDate 的转换

    一个时间戳字符串:NSString *timeStampStr =  @"1441602721"; 转换成时间     double unixTimeStamp          ...

  7. SQL的数据类型

    Character 字符串: 数据类型 描述 存储 char(n) 固定长度的字符串.最多 8,000 个字符. N的范围1-8000 varchar(n) 可变长度的字符串.最多 8,000 个字符 ...

  8. jQuery 遍历同胞(siblings)

    同胞拥有相同的父元素. 通过 jQuery,您能够在 DOM 树中遍历元素的同胞元素. 在 DOM 树中水平遍历 有许多有用的方法让我们在 DOM 树进行水平遍历: siblings() next() ...

  9. vector 与 set区别

    注:本文内容摘自网络,准确性有待验证,现阶段仅供学习参考.尊重作品作者成果,原文链接 :http://blog.csdn.net/wxdcxp/article/details/5279618 首先,v ...

  10. 【随记】数据库还原失败System.Data.SqlClient.SqlError: 无法执行 BACKUP LOG,因为当前没有数据库备份

    解决方法:去掉下图中箭头所指的项.