第三章 Unix/Linux 进程管理
一、知识点归纳以及收获内容
多任务处理
- 该部分主要介绍了多任务处理的定义,多任务处理指的时同时进行几项独立活动的能力。
- 多任务处理是通过在不同任务之间多路复用CPU执行时间来实现的。
- 如果切换速度够快,就会给人一种通知执行所有任务的错觉。这种逻辑并行性称为“并发”。
- 每个处理器也可以通过同时执行不同的任务实现多任务处理。
进程的概念
- 在操作系统中,任务也成为进程,进程是对映像的执行。
- 在Linux系统中:触发任何一个事件时,系统都会将它定义成为一个进程,并且给予这个进程一个ID,成为PID,同时依据启动这个进程的用户与相关属性关系,给予这个PID一组有效的权限设定
- 操作系统内核将一系列执行视为使用系统资源的单一实体。
- 系统资源包括内存空间、I/O设备以及最重要的CPU时间。PROC结构体包含了某个进程的所有信息。
- 程序放在实体磁盘当中,然后透过使用者的执行来触发,触发后会加载到内存中成为一个个体,那就是进程,为了操作系统可管理这个进程,因此进程有给予执行者的权限、属性参数,并包括程序所需要的脚本与数据或文件数据等,最后在给予一个PID
多任务处理系统
- type.h文件
- 定义了系统常熟和表示进程的简单PROC结构体
- ts.s文件
- 在32位GCC汇编代码中可实现进程上下文切换
- queue.c文件
- 可实现队列和链表操作函数。
- enqueue()函数按优先级将PROC输入队列中。在优先级队列中,具有相同优先级的进程按照FIFO的顺序排序。
- dequeue()函数可返回从队列或链表中删除的第一个元素。
- printList()函数可打印链表元素。
- t.c文件
- 定义MT系统数据结构、系统初始化代码和进程管理函数
- 多任务处理系统代码介绍
(1)init()初始化系统
(2)tswitch()实现进程上下文切换
(3)kfork()创建优先级为1的子进程
进程同步
一组进程为了协调其推进速度,在某些地方需要相互等待或者唤醒,这种进程间的相互制约就被称作是进程同步。这种合作现象在操作系统和并发式编程中属于经常性事件。
- 一个操作系统包含许多并发进程,这些进程可以彼此交互。进程同步是指控制和协调进程交互以确保其正确执行所需要的各项规则和机制。最简单的进程同步工具是休眠和唤醒操作
- 睡眠模式:当某进程需要某些当前没有的东西时,例如申请独占一个存储区域、等待用户通过标准输入来输入字符等,它就会在某个事件值上进入休眠状态,该事件值表示休眠的原因
- 唤醒模式:多个进程可能会进入休眠状态等待同一个事件,这是很自然的,因为这些进程可能都需要同一个资源,例如一台当前正处于繁忙状态的打印机。在这种情况下,所以这些进程都将休眠等待同一个事件值。
进程终止
- 正常终止
- 进程调用exit(value),发出_exit(value)系统调用来执行在操作系统内核中的kexit(value)
- 异常终止
- 进程因某个信号而异常终止
- 在这两种情况下,当进程终止时,最终都会在操作系统内核中调用 kexit()
I/O重定向
- 标准输入和输出
- 程序:指令+数据
- 读入数据:Input
- 输出数据:Output
打开的文件都有一个fd:file descriptor(文件描述符)
Linux给程序提供了三种I/O设备
标准输入(STDIN) -0 默认接受来自键盘的输入
标准输出(STDOUT) -1 默认输出到终端窗口
标准错误(STDERR) -2 默认输出到终端窗口
Unix/Linux中的进程
- 进程来源
- 操作系统内核会强行创建PID=0初始进程,然后,系统执行初始进程P0,然后,挂载一个跟文件系统,最后,P0复刻出一个子进程P1
- INIT和守护进程
- P1运行时,将执行映像更改为init程序,P1通常被称为init进程,P1的大部分子进程都是用来提供系统服务的,称为守护进程
- 登录进程
- sh编程
- 进程的执行模式
- 中断
- 陷阱
- 系统调用
进程管理的系统调用
- fork()
int pid = fork()
- fork()创建子进程并返回子进程的pid
- 进程终止
- 正常终止:当内核中的某个进程终止时,他会将_exit(value)系统调用中的值记录为进程PROC结构体中的退出状态。并通知他的二父进程并使该进程成为僵尸进程。父进程课通过系统调用找到僵尸子进程,获得其pid和退出状态
pid=wait(int *status)
- 异常终止:当某进程遇到异常时,他会陷入操作系统内核。内核的异常处理程序将陷阱错位类型转换为一个幻数,称为信号,将信号传递给进程,时进程终止。用户可以使用命令
kill -s signal_numeber pid
向通过pid识别的目标发送信号。
- 正常终止:当内核中的某个进程终止时,他会将_exit(value)系统调用中的值记录为进程PROC结构体中的退出状态。并通知他的二父进程并使该进程成为僵尸进程。父进程课通过系统调用找到僵尸子进程,获得其pid和退出状态
- 等待子进程终止
- 在任何时候,一个进程都可以使用
int pid = wait(int *status);
系统调用,等待僵尸子进程。
- 在任何时候,一个进程都可以使用
- 环境变量
- 各环境变量定义为:关键字=字符串
- 重要环境变量:
SHELL=/bin/bash TERM=xterm USER=kcw PATH=/usr/1oca1/bin:/usr/bin:/bin:/usr/local/games:/usr/games:./ HOME= / home /kcw
SHELL:指定将解释任何用户命令的sh。
TERM:指定运行sh时要模拟的终端类型。
USER:当前登录用户。
PATH:系统在查找命令时将检查的目录列表。
HOME:用户的主目录。在 Linux 中,所有用户主目录都在/home中。
在sh会话中,可以将环境变量设置为新的(字符串)值,如: HOME= / home / newhome
可通过EXPORT命令传递给后代sh,如expoert HOME
管道
-
管道时用于进程交换数据的单向进程件通信通道。管道有一个读取端和一个写入端。
1、管道命令处理
在Unix/Linux中,命令行cmd1 | cmd2
sh将通过一个进程运行cmd1,并通过另一个进程运行cmd2,他们通过一个管道连接在一起,因此cmd1的输出变为cmd2的输入2、命令管道
命令管道又叫FIFO(1)在sh中,通过mknod命令创建一个命令管道:
mknod mypipe p
(2)或在c语言中发出mknod()系统调用
int r = mknod("mypipe",s_IFIFP,0);
(3)进程可像访问普通文件一样发个文命名管道。
实践:
代码:
ps -ef|grep root
fork函数:
#include <unistd.h> #include <stdio.h> int main () { pid_t fpid; //fpid表示fork函数返回的值 int count=0; fpid=fork(); if (fpid < 0) printf("error in fork!"); else if (fpid == 0) { printf("i am the child process, my process id is %d\n",getpid()); count++; } else { printf("i am the parent process, my process id is %d\n",getpid()); count++; } printf("统计结果是: %d\n",count); return 0; }
标签:fork,第三章,int,系统,pid,笔记,学习,进程,多任务处理 From: https://www.cnblogs.com/MRC-/p/16773712.html