什么是多任务

        多任务:让系统具备同时具备处理多个任务的能力

        实现多任务的方式:多进程;多线程

进程

什么是进程

        正在运行的程序,其运行过程中需要消耗内存和CPU,是操作系统资源分配的最小单位

        main.c(程序)(硬盘)-----a.out(程序)(硬盘)-------./a/out(进程)(内存)

程序和进程的区别:

        程序是静态的数据集合,存储在硬盘空间,程序运行起来可以产生进程,而一个程序可以产生多个进程;

        进程是一个程序动态执行的过程,需要消耗内存和CPU,具备动态生命周期,从产生到调度再到消亡,一个进程可以执行多个程序

进程的产生

        进程产生时,操作系统会为其分配0-4G的虚拟内存空间,其中1G用于内核,剩下3G用于四大区

        内核作用:文件管理,进程管理,内存管理......

        内存空间四区域:栈区、堆区、数据区、文本区

                栈区:保存局部变量、函数的形参和返回值;保存函数调用关系(保护现场和恢复现场)

                堆区:由开发人员手动分配;使用完要手动释放

                数据区:

                        字符串常量区:保存字符串常量

                        bss段:未初始化的全局变量;未初始化的静态变量(static)。这是由于bass段初始时按位清零

                        只读数据段:已初始化的全局变量;已初始化的静态变量

                文本区:存放指令代码和常量

进程的调度

        cpu:数据处理速度快,遵行宏观并行,微观串行的调度方式,即在微观上先执行进程一个再进程另一个,而在宏观上显示的是同时进行

        cpu调度算法:

                1)时间片轮询算法,会根据每个任务的执行情况分配时间片,每个任务运行一定时间再跳到下一个任务

                2)先来先服务,后来后服务(任务队列)

                3)短作业优先调度,优先处理完时间较短的程序

                4)高优先级限制性,低优先级后执行,有的cpu会高优先级任务打断低优先级任务

进程的状态

        操作系统进程的三态图

        Linux操作系统进程状态:

                运行态(用户运行态、内核运行态):正在执行,且被CPU任务调度所执行的进程

                就绪态(R):正在执行,没有CPU任务调度执行的进程(只缺少CPU)

                可唤醒等待态(S):也称睡眠态,阻塞等待资源的进程,类似于阻塞态,可以被主动唤醒

                不可唤醒等待态(D):不想被CPU任务调度所打断的进程任务可设置未该状态,只能自己睡醒

                暂停态(T):被暂停执行的进程

                僵尸态(Z):进程直接结束,空间没有被回收

                结束态(X):进程执行结束,空间被回收

进程的消亡

        1,进程执行结束(进程退出)

        2,回收进程资源空间

进程相关密令

        1. ps  -aux:查看进程相关参数,以下为参数名称

                USER:创建的用户

                PID:进程的ID号

                VIRT、SHR、S:与内存有关

                %CPU,%MEM:CPU占用率,内存占用率

                TTY:当前进程关联的终端,如果是问号“?”则表示该进程与任何终端都不关联

                STAT:表示当前进程的状态

                START:进程启动的时间

                COMMAND:进程名称

                PR    NI:该进程的优先级,PR越小越高

          |  : 管道  ,前面命令的输出作为后面命令的输入

          grep : 字符串查找:在输入中查找和后面字符串相关的数据      

          所以可以用ps - aux | grep 进程名来查找某一进程,其他密令也可以通过类似操作
        2. top:动态查看进程的相关参数

        3. ps -ef:查看该进程的ID和父进程ID

                PPID :父进程ID号
                        父进程:产生子进程的进程称为父进程
                        子进程:父进程产生出来的新进程即为该父进程的子进程

                STIME:启动的时间

                TIME:被CPU调度的时间

                CMD:进程名称             

        4. pstree:查看进程的产生关系

           pstree -p:查看进程的产生关系(有PID号)

           pstree -sp  进程PID号:查看某个指定的进程的产生关系

        5. kill -信号的编号或者信信号的名称  PID:向进程发送信号,让进程的状态发生变化 

                kill -l:查看系统支持的信号

                例子:

                        kill -9 PID、kill -SIGKILL PID、killall -9  进程名称:结束PID号的进程

                        kill -19 PID:将状态改为休眠态                  
        6. jobs:查看当前终端的后台进程

                 带加号“+”的表示是前台进程,不带的是后台进程
        7.fg 后台进程编号:让后台进程切换成前台进程

进程相关编程

        进程创建:fork()

        进程调度:操作系统完成

        进程消亡:

                1,进程退出:return、exit()相关函数

                        注意:必须是main中的return

                2,回收资源空间:wait()、waitpid()

                        僵尸进程:进程退出后,但其资源空间未被父进程回收

                        如何避免僵尸进程产生:
                                1.  子进程退出后,父进程及时为其回收资源空间

                                2.  让该进程成为一个孤儿进程,结束时被操作系统中的系统进程回收。

                                3.孤儿进程:父进程先消亡,其对应的子进程成为一个孤儿进程,会被系统进程所收养,例如守护类的进程就是孤儿进程

fork()

        功能:通过拷贝父进程产生一个新的子进程,会有两个进程同时在工作,所以如下代码会有两次。子进程完全拷贝父进程0-3G的虚拟内存空间。子进程拷贝父进程PCB(进程控制块)中的部分内容:PID不拷贝

        返回值:

        注:

                1. 子进程完完整整拷贝父进程0-3G虚拟内存空间,至于先调度谁取决于CPU,但是子进程是从fork下一行开始运行
                2. 父子进程栈区、数据区、文本区、堆区完全独立,数据不共享
                3. 要想共享数据,需要使用进程间通信方式实现

        值得注意的是,fork返回的pid号只是作为父子进程内部的自我标识,而非真正的pid号,所以在通过类似ps -ef | grep ./a.out显示出的pid号并不为子进程返回的0。可以通过子进程的PPID等于父进程的PID来区分父子进程

getpid()、getppid()

        功能:获取该进程的pid号,获得父进程的pid号

sleep()

        功能:使进程休眠一定时间

exit()

        功能分为三种情况

                exit()、_exit():结束一个进程

                exit(0):正常退出

                exit(!0):由于进程产生某种问题,需要主动退出进程

wait()

        功能:阻塞等待回收子进程的资源空间(即使子进程先结束)

        参数:保存子进程消亡状态的变量地址,如果是NULL,则不保存子进程退出的状态

                wait的参数可以接收子进程返回的值,这个数字代表了一个具体的消亡状态,在系统中定义了不同的宏

        返回值:成功则为回收到的子进程的PID号,失败则为-1

        效果:造成同步的效果。进程本身是异步的效果,即这个进行这个那个进行那个,而同步就是导致进程有了进行的顺序

        那么什么是阻塞等待回收呢?如果父进程使用了该函数,则子进程结束后才会继续进行父进程的代码,以下为例

        第一个为没加wait时的结果,第二个为加了wait后的结果

waitpid()

        功能:回收指定子进程的资源空间,和wait功能类似,但是比wait更灵活

        参数:

                pid:

                        >0:回收指定ID的子进程

                        0:回收和当前调用waitpid一个组的所有子进程,回收组内的所有子进程

                        -1:回收组内组外的任意子进程

                        <-1:回收指定进程组内的任意子进程(例如-100,表示等待回收GID(组ID)=100的进程组中的任意子进程)

                wstatus:子进程退出时候的状态,如果不关注退出状态则用NULL

                options:如果是0则表示回收过程会阻塞等待;如果是WNOHANG表示非阻塞模式回收

                返回值:成功则为接收资源的子进程pid,失败则为-1,如果设定为非阻塞且没有回收到子进程则为0

子进程资源空间回收策略

        1,wait阻塞回收:一般情况下,父进程专门负责资源回收

        2,waitpid非阻塞方式回收:必须搭配轮询方式回收

        3,不回收:子进程的任务需要一直执行

        4,异步回收:当子进程结束时通知父进程进行回收

exec函数族

        作用:在进程内执行另外一个可执行文件

execl

        l:list,以列表的形式传递

                参数:要执行的文件的路径和名称(包括系统文件,可以通过whereis+命令查看文件的位置);执行该可执行文件时需传递的参数;多个和前面相似的参数,若没有则填NULL

                返回值:出错则为-1

                本质:将文本区的指令代码替换成exec要执行的文件的指令,整个过程没有新的进程产生

        结果只输出了new,所以该类函数是代替,而非产生

execlp

                p:path,以路径的方式传递,路径一般为系统路径

                功能:从PATH指定的系统路径下寻找该可执行文件

                参数:需要执行的可执行文件的文件名(系统路径下已有的),其余与execl相同

execv

        v:vector,以容器的方式传递

        参数: 要执行的文件的路径和名称;将参数放在一个数组内,传递这个数组的指针,数组内参数形式和execl相同

        e:env,以环境变量的方式传递,可以直接在终端输入env查看环境变量

sysytem

        参数:指令字符串,例如ls,touch

        该函数与exec不同,它重新产生了一个子进程,该子进程运行过后继续进行父进程的代码,所以相当于父进程使用了wait()

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐