14 exec/fork/wait cycles for Process Management

1 Executing a Programing

  1. exec将加载新的进程,并替换掉现在的进程
  2. exev execvp execvpe
    1. exev
    2. execvp
    3. execvpe

1.1 Using execv and execvp

  1. execv,需要输入绝对路径
/*execv_ls-l.c*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char * argv[]){

  //argv array for: /bin/ls -l
  char * ls_args[] = { "/bin/ls" , "-l", NULL};
  //                                  ^
  //       all argv arrays must be ___| 
  //       NULL terminated       

  //execute the program
  execv(   ls_args[0],     ls_args);
  //           ^              ^
  //           |              |
  // Name of program        argv array
  // is ls_args[0]          for ls_args


  //only get here on error
  perror("execv");
  return 2;
}
  1. execvp,可以加载$path,所以不需要输入全路径
aviv@saddleback: demo $ cat execvp_ls-l.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char * argv[]){

  //argv array for: ls -l
  char * ls_args[] = { "ls" , "-l", NULL};
  //                    ^ 
  //  use the name ls
  //  rather than the
  //  path to /bin/ls
  execvp(   ls_args[0],     ls_args);


  //only get here on error
  perror("execv");
  return 2;
}

1.2 The argv[] argument to execv and execvp

char * ls_args[] = { "ls" , "-l", NULL};

            .-----.
ls_args ->  |  .--+--> "/bin/ls"
            |-----|
            |  .--+--> "-l"
            |-----|
            |  .--+--> NULL
            '-----'

2 Creating a new Process

1.exec是在当前进程里执行,fork是新创建了一个进程

2.1 fork()

1.所有的进程都产生于其他进程,最初的进程是init
2.fork方法返回两次,一次是父进程(返回子进程的id),一次是子进程(返回0)
3.子进程时父进程的镜像

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(){

  pid_t c_pid;
  c_pid = fork(); //duplicate                                                                                                                                                
  if( c_pid == 0 ){
    //child: The return of fork() is zero                                                                                                                                    
    printf("Child: I'm the child: %d\n", c_pid);
  }else if (c_pid > 0){
    //parent: The return of fork() is the process of id of the child                                                                                                         
    printf("Parent: I'm the parent: %d\n", c_pid);
  }else{
    //error: The return of fork() is negative                                                                                                                                
    perror("fork failed");
    _exit(2); //exit failure, hard                                                                                                                                           
  }
  return 0; //success                                                                                                                                                        
}

2.2 Process identifiers or pid

1.每一个进程都有一个id,叫pid
2.pid占用2个字节,类型是pid_t
3.父进程fork返回子进程的id,子进程fork返回0,出错fork返回-1
4.pstree 查看进程的继承关系

2.3 Retrieving Process Identifiers: getpid() and getppid()

  1. fork机制,父知道子pid,子不知道父pid,使用getppid
  2. 父不知道自己的id,使用getpid
  3. shell执行进程,就是fork
  4. shell是进程的父进程,使用echo $$来查看当前shell的进程
//retrieve the current process id
pid_t getpid(void);

//retrieve the parent's process id
pid_t getppid(void);
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(){
  pid_t pid, ppid;

  //get the process'es pid
  pid = getpid();
  //get the parrent of this process'es pid
  ppid = getppid();
  printf("My pid is: %d\n",pid);
  printf("My parent's pid is %d\n", ppid);
  return 0;
}

3 Waiting on a child with wait()

  1. wait()父进程调用,返回子进程状态的变化
  2. 当父进程调用wait()将会阻塞,直到子进程状态发生变化
  3. wait返回子子进程的pid,如果没有子进程,则返回-1
  4. wait需要整型指针参数,记录子进程退出的状态
/*get_exitstatus.c*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/wait.h>

int main(){

  pid_t c_pid, pid;
  int status;

  c_pid = fork(); //duplicate

  if( c_pid == 0 ){
    //child
    pid = getpid();

    printf("Child: %d: I'm the child\n", pid, c_pid);
    printf("Child: sleeping for 2-seconds, then exiting with status 12\n");

    //sleep for 2 seconds
    sleep(2);

    //exit with statys 12
    exit(12);

  }else if (c_pid > 0){
    //parent

    //waiting for child to terminate
    pid = wait(&status);

    if ( WIFEXITED(status) ){
      printf("Parent: Child exited with status: %d\n", WEXITSTATUS(status));
    }

  }else{
    //error: The return of fork() is negative
    perror("fork failed");
    _exit(2); //exit failure, hard
  }

  return 0; //success                                                                                                                                                        
}

4 Fork/Exec/Wait Cycle

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值