• 转: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()来等待,直到子进程调用结束。

  • 相关阅读:
    博客园美化-SimpleMemor
    Java多线程-synchronized与ReentrantLock
    springboot中删除@SessionAttributes注解的属性
    SSM整合笔记
    Spring中xml和注解方式使用AOP
    Mysql 数据库基本操作
    Mysql 二进制包安装
    named piped tcp proxy 下载
    docker容器中日志文件过大处理方法
    自动做bond的脚本
  • 原文地址:https://www.cnblogs.com/studyskill/p/7728995.html
Copyright © 2020-2023  润新知