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


      通过调用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
    ",(long)getpid());      //打印子进程的ID
      }
      else{
        printf("I am parent %ld
    ",(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...........
    ");
                     if(execl("/bin/ls","ls","-a",NULL)<0)
                     {
                          fprintf(stderr,"execl failed:%s",strerror(errno));
                          return -1;
                     }
                 }
                 if(fork()==0)
                 {
                     printf("execv...........
    ");
                     if(execv("/bin/ls",arg)<0)
                     {
                         fprintf(stderr,"execl failed:%s
    ",strerror(errno));
                         return -1;
                     }
                 }
                 if(fork()==0)
                 {
                     printf("execlp...........
    ");
                     if(execlp("ls","ls","-a",NULL)<0)
                     {
                         fprintf(stderr,"execl failed:%s",strerror(errno));
                         return -1;
                     }
                 }
                 if(fork()==0)
                 {
                     printf("execvp...........
    ");
                     if(execvp("ls",arg)<0)
                     {
                         fprintf(stderr,"execl failed:%s
    ",strerror(errno));
                         return -1;
                     }
                 }
                 if(fork()==0)
                 {
                     printf("execle...........
    ");
                     if(execle("/bin/ls","ls","-a",NULL,envp)<0)
                     {
                         fprintf(stderr,"execl failed:%s",strerror(errno));
                         return -1;
                     }
                 }
                 if(fork()==0)
                 {
                     printf("execve...........
    ");
                     if(execve("/bin/ls",arg,envp)<0)
                     {
                         fprintf(stderr,"execl failed:%s
    ",strerror(errno));
                         return -1;
                     }
                 }
    
              return 0;
            }
  • 相关阅读:
    python-pytest使用
    PyCharm2021使用教程 --- 11、PyCharm必备插件
    PyCharm2021使用教程 --- 10、PyCharm中实用小技巧
    PyCharm2021使用教程 ---9、PyCharm中的搜索技巧(文件/函数/内容)
    PyCharm2021使用教程 --- 8、版本控制
    PyCharm2021使用教程 --- 7、如何使用DeBug调试程序
    PyCharm2021使用教程 --- 6、如何运行程序
    PyCharm2021使用教程 --- 5、PyCharm的基本配置
    PyCharm2021使用教程 --- 4、菜单栏详细介绍
    PyCharm2021使用教程 --- 3、使用pycharm创建项目
  • 原文地址:https://www.cnblogs.com/zjzsky/p/3481254.html
Copyright © 2020-2023  润新知