UNIX高级编程【深入浅出】进程控制(中)

本文详细解释了进程的概念,包括其基本环境(内存空间、程序计数器、寄存器、文件描述符、环境变量和资源限制),进程替换的方法(如execl和fork),以及父子进程的区别、PID、进程控制块(PCB)和vfork与execve的特性。
摘要由CSDN通过智能技术生成

目录

什么是进程

进程都有哪些基本环境

如何实现进程替换

ps

top

进程的优先级

进程id---》PID

每一个进程都有父进程

尝试创建一个子进程

新的进程(子进程)复制了调用进程(父进程)哪些属性

父子进程的区别

PCB进程控制块

fork应用场景

fork(2) 和 vfork(2)的区别

子进程执行不同的程序


  1. 什么是进程

    1. 它是计算机中正在运行的一个程序的实例,是操作系统进行任务调度和资源分配的基本单位
  2. 进程都有哪些基本环境

     
    1. 内存空间:每个进程都有自己的地址空间,用于存储程序的代码、数据和堆栈等。操作系统为每个进程分配一块独立的内存空间,使得进程之间可以相互隔离。
    2. 程序计数器(Program
      Counter):程序计数器是一个存储当前正在执行指令的地址的寄存器。它指示了下一条将要被执行的指令的位置。当进程被挂起或切换到其他进程时,程序计数器的值会被保存,以便在恢复执行时能够继续从上次中断的位置继续执行。
    3. 寄存器:寄存器是用于暂存数据和指令的快速存储空间。它们用于存储当前进程的状态,包括程序计数器、堆栈指针、变量值和函数调用的返回地址等。
    4. 文件描述符表:每个进程都有一个文件描述符表,用于管理打开的文件和其他I/O设备。文件描述符是一个非负整数,用于标识打开文件或设备的引用。通过文件描述符,进程可以读取和写入文件、网络通信等。
    5. 环境变量:环境变量是进程运行时可用的一组系统变量。它们包含了一些关键的运行时信息,如路径、语言设置和系统配置等。进程可以使用环境变量来访问这些信息,并根据需要进行适当的操作。
    6. 资源限制:操作系统可以对进程应用资源限制,如CPU时间、内存使用量、打开文件数等。这些限制可以帮助操作系统管理资源的分配和保护系统的稳定性。
  3. 如何实现进程替换

    1. int execl(const char *path, const char *arg, ...
              /* (char  *) NULL */);
      int execlp(const char *file, const char *arg, ...
              /* (char  *) NULL */);
      int execle(const char *path, const char *arg, ...
              /*, (char *) NULL, char * const envp[] */);
      int execv(const char *path, char *const argv[]);
      int execvp(const char *file, char *const argv[]);
      int execvpe(const char *file, char *const argv[],
                char *const envp[]);
                都调用下面,系统直接调用函数
      int execve(const char *filename, char *const argv[],
               char *const envp[]);

  4. ps

    1. 进程快照,执行ps命令期间进程的状态
    2. ps aux
      1. PID STATE COMMAND
    3. ps axj
      1. PPID PID PGID SID
    4. ps axm -L
      1. 线程
    5. ps elf
      1. 父子关系
  5. top

    1. 实时显示进程状态
    2. < >翻页
    3. q退出
  6. 进程的优先级

    1. 进程的运行时依赖cpu的
    2. nice -19~20
  7. 进程id---》PID

    1. 系统中第一个运行的用户态进程是init,init ID是1
    2. 新创建的进程的PID > 1
    3. 如何查看进程PID---》ps / top
    4. 获取进程PID的函数getpid(2)
    5. pid_t类型 实际上就是整型
  8. 每一个进程都有父进程

    1. 新的进程的创建是通过复制父进程而得到的
    2. 内核预留创建进程的接口fork(2)
    3. 命令行中执行的命令谁是父进程呢?
      1. bash
  9. 尝试创建一个子进程

    1. fork(2)

  1. 新的进程(子进程)复制了调用进程(父进程)哪些属性

    1. 进程表项
    2. 文件屏蔽字umask
    3. 根目录
    4. 当前工作目录
    5. 环境表
    6. 进程的资源限制
    7. 用户id,组id
    8. 控制终端
    9. 虚拟地址空间
    10. 标准io缓存区
    11. 信号的行为 和 屏蔽
  2. 父子进程的区别

    1. PID
    2. PPID
    3. 子进程内核记录的时间会初始化为0
    4. 文件锁(14章)
    5. 未决信号(10章)
    6. 未决闹钟(10章)
  3. PCB进程控制块

    1. 每一个进程都有一个PCB,控制程序的执行,例如程序的执行位置
    2. 当子进程创建成功,会复制父进程的PCB,那么程序执行的位置也与父进程一致
  4. fork应用场景

    1. 希望父子进程执行不同的代码段。主要在网络服务中比较常见,例如服务器父进程接受客户端的请求,创建子进程处理业务,父进程用户接受
    2. 子进程执行不同的程序。主要应用在shell
  5. fork(2) 和 vfork(2)的区别

    1. vfork创建的子进程,会阻塞父进程的运行,等待子进程运行结束父进程在执行
    2. vfork创建的子进程会与父进程共享虚拟地址空间(子进程的终止调用_exit(2))
  6. wait(2)函数

    1. 所谓的收尸就是父进程为得到子进程的终止状态,并释放子进程资源的过程
    2. waitpid(2)
      1. 可以指定子进程的进程组
    3. 为任意子进程收尸
  7. 子进程执行不同的程序

    1. exec(3) 
    2. 进程的替换,shell的实现需要用到
    3. 内核提供进程替换的api只有execve(2)
    4. int execl(const char *path, const char *arg, ...
              /* (char  *) NULL */);
      int execlp(const char *file, const char *arg, ...
              /* (char  *) NULL */);
      int execle(const char *path, const char *arg, ...
              /*, (char *) NULL, char * const envp[] */);
      int execv(const char *path, char *const argv[]);
      int execvp(const char *file, char *const argv[]);
      int execvpe(const char *file, char *const argv[],
                char *const envp[]);
                都调用下面,系统直接调用函数
      int execve(const char *filename, char *const argv[],
               char *const envp[]);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值