Linux学习笔记12——Unix中的进程

系统 1973 0

  通过调用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==-
      
        1
      
      
        ){                                 
        
          //创建子进程失败
        
        

    perror(
      
      
        "
      
      
        Failed to fork
      
      
        "
      
      
        );

    
      
      
        return
      
      
        1
      
      
        ;

  }

  
      
      
        if
      
      (childpid==
      
        0
      
      
        ){                                  
        
          //创建子进程成功
        
        

    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()==
      
        0
      
      
        )

             {

                 printf(
      
      
        "
      
      
        execl...........\n
      
      
        "
      
      
        );

                 
      
      
        if
      
      (execl(
      
        "
      
      
        /bin/ls
      
      
        "
      
      ,
      
        "
      
      
        ls
      
      
        "
      
      ,
      
        "
      
      
        -a
      
      
        "
      
      ,NULL)<
      
        0
      
      
        )

                 {

                      fprintf(stderr,
      
      
        "
      
      
        execl failed:%s
      
      
        "
      
      
        ,strerror(errno));

                      
      
      
        return
      
       -
      
        1
      
      
        ;

                 }

             }

             
      
      
        if
      
      (fork()==
      
        0
      
      
        )

             {

                 printf(
      
      
        "
      
      
        execv...........\n
      
      
        "
      
      
        );

                 
      
      
        if
      
      (execv(
      
        "
      
      
        /bin/ls
      
      
        "
      
      ,arg)<
      
        0
      
      
        )

                 {

                     fprintf(stderr,
      
      
        "
      
      
        execl failed:%s\n
      
      
        "
      
      
        ,strerror(errno));

                     
      
      
        return
      
       -
      
        1
      
      
        ;

                 }

             }

             
      
      
        if
      
      (fork()==
      
        0
      
      
        )

             {

                 printf(
      
      
        "
      
      
        execlp...........\n
      
      
        "
      
      
        );

                 
      
      
        if
      
      (execlp(
      
        "
      
      
        ls
      
      
        "
      
      ,
      
        "
      
      
        ls
      
      
        "
      
      ,
      
        "
      
      
        -a
      
      
        "
      
      ,NULL)<
      
        0
      
      
        )

                 {

                     fprintf(stderr,
      
      
        "
      
      
        execl failed:%s
      
      
        "
      
      
        ,strerror(errno));

                     
      
      
        return
      
       -
      
        1
      
      
        ;

                 }

             }

             
      
      
        if
      
      (fork()==
      
        0
      
      
        )

             {

                 printf(
      
      
        "
      
      
        execvp...........\n
      
      
        "
      
      
        );

                 
      
      
        if
      
      (execvp(
      
        "
      
      
        ls
      
      
        "
      
      ,arg)<
      
        0
      
      
        )

                 {

                     fprintf(stderr,
      
      
        "
      
      
        execl failed:%s\n
      
      
        "
      
      
        ,strerror(errno));

                     
      
      
        return
      
       -
      
        1
      
      
        ;

                 }

             }

             
      
      
        if
      
      (fork()==
      
        0
      
      
        )

             {

                 printf(
      
      
        "
      
      
        execle...........\n
      
      
        "
      
      
        );

                 
      
      
        if
      
      (execle(
      
        "
      
      
        /bin/ls
      
      
        "
      
      ,
      
        "
      
      
        ls
      
      
        "
      
      ,
      
        "
      
      
        -a
      
      
        "
      
      ,NULL,envp)<
      
        0
      
      
        )

                 {

                     fprintf(stderr,
      
      
        "
      
      
        execl failed:%s
      
      
        "
      
      
        ,strerror(errno));

                     
      
      
        return
      
       -
      
        1
      
      
        ;

                 }

             }

             
      
      
        if
      
      (fork()==
      
        0
      
      
        )

             {

                 printf(
      
      
        "
      
      
        execve...........\n
      
      
        "
      
      
        );

                 
      
      
        if
      
      (execve(
      
        "
      
      
        /bin/ls
      
      
        "
      
      ,arg,envp)<
      
        0
      
      
        )

                 {

                     fprintf(stderr,
      
      
        "
      
      
        execl failed:%s\n
      
      
        "
      
      
        ,strerror(errno));

                     
      
      
        return
      
       -
      
        1
      
      
        ;

                 }

             }



          
      
      
        return
      
      
        0
      
      
        ;

        }
      
    

 

 

Linux学习笔记12——Unix中的进程


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论