zoukankan      html  css  js  c++  java
  • 转:Linux创建进程

    转:http://www.cnblogs.com/GT_Andy/archive/2011/06/21/2086129.html

     我们都知道,进程就是正在执行的程序。而在Linux中,可以使用一个进程来创建另外一个进程。这样的话,Linux的进程的组织结构其实有点像Linux目录树,是个层次结构的,可以使用pstree命令来查看。在最上面是init程序的执行进程。它是所有进程的老祖宗。Linux提供了两个函数来创建进程。

    1.fork()

      fork()提供了创建进程的基本操作,可以说它是Linux系统多任务的基础。该函数在unistd.h库中声明。  

     
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
      
    int main()
    {
        printf( "创建进程前 " );
        pid_t pid = fork();
      
        if( !pid ){
            printf( "我是子进程哟,我的PID是:%d " ,getpid() );
        }else if( pid>0 ){
            printf( "我是父进程,我的PID是:%d,我的子进程PID是:%d ",getpid(),pid );
        }else{
            printf( "创建进程失败了哟 " );
            exit(1);
        }
      
        return 1;
    }

      在调用fork()之前,只有一个进程,但是fork()之后,将产生一个该进程的子进程,该子进程完全复制父进程,此时父子两个进程同时运行。在fork()的时候,如果返回的是0,则说明该进程是子进程。如果返回大于0则说明是父进程。如果小于0(其实是-1),则说明创建进程失败了。

      每个进程都有一个唯一标示符,即PID,可以使用getpid()来获取。父进程返回的pid其实是子进程的pid。

      貌似这样看,fork()之后也没有什么作用。其实不然,如果fork()之后跟其他linux功能使用,还是用处很大的。比如我们可以在父子进程中通过通信协议来通信,就可以协同完成一些任务了。

    2.exec系列函数

      如果只有fork(),肯定是不完美的,因为fork()只能参数一个父进程的副本。而exec系列函数则可以帮助我们建立一个全新的新进程。

     
    int execl( const char *path, const char *arg, ...);
    int execlp( const char *file, const char *arg, ...);
    int execle( const char *path, const char *arg , ..., char* const envp[]);
    int execv( const char *path, char *const argv[]);
    int execvp( const char *file, char *const argv[]);

    以上函数在unistd.h声明。

    下面我们以execl()函数为例:

     
    #include <stdio.h>
    #include <unistd.h>
      
    int main()
    {
        execl("/bin/ls","ls","-l",NULL);
      
        printf("如果execl执行失败,这个就会打印出来了 ");
        return 1;
    }

    该程序运行到execle()时,载入ls程序,并且覆盖当前程序的空间。这样就参数了一个新的进程,但是注意,这个新进程的PID跟载入它的进程是一样的。

    3.fork()和exec()一起调用

      fork()可以创建子进程,但是子进程只是父进程的副本。我们可以利用exec()函数在子进程来重新载入一个全新的进程。下面看一个两个函数联用的列子。

     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
      
    int main()
    {
        pid_t pid = fork();
        switch( pid )
        {
        case 0:
            printf("子进程 ");
            execl("/bin/ls","ls","-l",NULL);
        case -1:
            printf("fork失败了 ");
            exit(1);
        default:
            wait(NULL);
            printf("完成了哟! ");
            exit(0);
        }
    }

    首先,fork建立子进程,然后在子进程中使用execl()产生一个ls程序的进程。而父进程则调用wait()来等待,直到子进程调用结束。

     我们都知道,进程就是正在执行的程序。而在Linux中,可以使用一个进程来创建另外一个进程。这样的话,Linux的进程的组织结构其实有点像Linux目录树,是个层次结构的,可以使用pstree命令来查看。在最上面是init程序的执行进程。它是所有进程的老祖宗。Linux提供了两个函数来创建进程。

    1.fork()

      fork()提供了创建进程的基本操作,可以说它是Linux系统多任务的基础。该函数在unistd.h库中声明。  

     
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
      
    int main()
    {
        printf( "创建进程前 " );
        pid_t pid = fork();
      
        if( !pid ){
            printf( "我是子进程哟,我的PID是:%d " ,getpid() );
        }else if( pid>0 ){
            printf( "我是父进程,我的PID是:%d,我的子进程PID是:%d ",getpid(),pid );
        }else{
            printf( "创建进程失败了哟 " );
            exit(1);
        }
      
        return 1;
    }

      在调用fork()之前,只有一个进程,但是fork()之后,将产生一个该进程的子进程,该子进程完全复制父进程,此时父子两个进程同时运行。在fork()的时候,如果返回的是0,则说明该进程是子进程。如果返回大于0则说明是父进程。如果小于0(其实是-1),则说明创建进程失败了。

      每个进程都有一个唯一标示符,即PID,可以使用getpid()来获取。父进程返回的pid其实是子进程的pid。

      貌似这样看,fork()之后也没有什么作用。其实不然,如果fork()之后跟其他linux功能使用,还是用处很大的。比如我们可以在父子进程中通过通信协议来通信,就可以协同完成一些任务了。

    2.exec系列函数

      如果只有fork(),肯定是不完美的,因为fork()只能参数一个父进程的副本。而exec系列函数则可以帮助我们建立一个全新的新进程。

     
    int execl( const char *path, const char *arg, ...);
    int execlp( const char *file, const char *arg, ...);
    int execle( const char *path, const char *arg , ..., char* const envp[]);
    int execv( const char *path, char *const argv[]);
    int execvp( const char *file, char *const argv[]);

    以上函数在unistd.h声明。

    下面我们以execl()函数为例:

     
    #include <stdio.h>
    #include <unistd.h>
      
    int main()
    {
        execl("/bin/ls","ls","-l",NULL);
      
        printf("如果execl执行失败,这个就会打印出来了 ");
        return 1;
    }

    该程序运行到execle()时,载入ls程序,并且覆盖当前程序的空间。这样就参数了一个新的进程,但是注意,这个新进程的PID跟载入它的进程是一样的。

    3.fork()和exec()一起调用

      fork()可以创建子进程,但是子进程只是父进程的副本。我们可以利用exec()函数在子进程来重新载入一个全新的进程。下面看一个两个函数联用的列子。

     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
      
    int main()
    {
        pid_t pid = fork();
        switch( pid )
        {
        case 0:
            printf("子进程 ");
            execl("/bin/ls","ls","-l",NULL);
        case -1:
            printf("fork失败了 ");
            exit(1);
        default:
            wait(NULL);
            printf("完成了哟! ");
            exit(0);
        }
    }

    首先,fork建立子进程,然后在子进程中使用execl()产生一个ls程序的进程。而父进程则调用wait()来等待,直到子进程调用结束。

  • 相关阅读:
    模板 无源汇上下界可行流 loj115
    ICPC2018JiaozuoE Resistors in Parallel 高精度 数论
    hdu 2255 奔小康赚大钱 最佳匹配 KM算法
    ICPC2018Beijing 现场赛D Frog and Portal 构造
    codeforce 1175E Minimal Segment Cover ST表 倍增思想
    ICPC2018Jiaozuo 现场赛H Can You Solve the Harder Problem? 后缀数组 树上差分 ST表 口胡题解
    luogu P1966 火柴排队 树状数组 逆序对 离散化
    luogu P1970 花匠 贪心
    luogu P1967 货车运输 最大生成树 倍增LCA
    luogu P1315 观光公交 贪心
  • 原文地址:https://www.cnblogs.com/studyskill/p/7728995.html
Copyright © 2011-2022 走看看