Linux应用编程基础--(4)多进程基础1

要想进行多进程编程,我们需要先了解一下Linux中多进程的机制:

一、Linux下的多任务机制:
RTOS(实时操作系统)
时间片转轮和内核抢占
多任务处理:指的是用户可以在同一时间内运行多个应用程序,每一个正在执行的应用程序叫做任务。
多任务操作系统中3个基本概念:
任务、进程、线程
二、进程的基本概念:
进程是指一个具有独立功能的程序在某个数据集合上的一次动态执行。它是操作系统进行资源分配和调度的基本单元。
补充:进程与程序的区别?
程序是静态的,它是保留在磁盘上指令的有序集合,没有任何执行概念。
进程是一个动态概念,它是程序执行的过程,包括创建调度和消亡。
进程的特点:
并发性、动态性、交互性、独立性
进程的标识:
进程号 PID 用ps指令查看 ,PID是唯一地标识一个进程。
Linux中常见的三种进程类型:
交互式进程:由shell控制和运行的,既可以在前台也可在后台运行。
批处理进程:此类不属于任何终端,提交到执行队列中顺便执行。
守护进程:在后台运行的程序,一般为系统服务进程,在系统开启是执行,系统关闭是结束。
三、进程的结构:
进程不仅包括程序的指令和数据,还包括程序计数器和处理器的所有寄存器以及存储临时数据的进程堆栈。
在Linux中用来维护一个进程必须的一个结构体 task_stauct
task_struct结构体中有两个重要的: state进程状态 pid 进程号
用户空间的几个功能区域:
只读段:包含程序的代码(.init .text)和只读数据(.rodata)
数据段:存放全局变量和静态变量,已初始化的在.data 未初始化的在.bss
栈区:由系统自动分配,函数的参数值,局部变量和返回地址
堆区:动态内存分配,由用户申请释放,
共享库的内存映射区:Linux的动态链接器和其他共享库代码的映射区域。



1,进程的状态:
RUNNING 运行态 :进程准备运行或者正在运行。
INTERRUPTIBLE 可中断的阻塞态 :进程正在(浅度)睡眠态,等待资源到来时被唤醒,也可通过其他进程信号或时钟中断唤醒进入运行队列。
UNINTERRUPTIBLE 不可中断的阻塞态 :深度睡眠状态,只有使用wake_up()函数明确唤醒时才能转换到可运行的就绪状态。
STOPPED 暂停态 : 当进程接受到洗脑SIGSTOP【Ctrl+z】 就会进去暂停状态。
ZOMBIE 僵尸态 :
当进程已经停止运行时,其父进程还没有询问其状态,未释放PCB,择该进程成为僵尸进程。
当子进程先退出,父进程后退出切没有回收子进程,子进程就变成的僵尸进程(僵尸进程不可kill,除非kill其父进程)
回收的三种方法:
父进程调用 wait waitpid SIGCHLD
父进程在创建子进程时通知内核不想回收该子进程
父进程没有回收,由init成为该子进程的继父进程,当子进程结束时回收它。
DEAD 消亡态 : 这是进程的最终状态,父进程调用wait函数族回收,子进程彻底删除。
进程状态图:

2,进程的模式:
用户态和内核态。
用户态:只能访问用户空间,只能通多系统调用想设备驱动程序或其他内核模式的代码请求访问,用户模式可以缺页,
内核态:代码课无限制的访问所有处理器指令集及全部内存和IO空间,但是内核不允许缺页。
四,进程的管理调度
1,进程的启动Linux提供的相关命令
手动启动:由用户输入命令直接启动进程,前台和后台运行
调度启动:系统根据用户事先设定自行启动进程
at 在指定时刻执行相关进程
cron 周期性执行相关进程
at cron 的相关指令及其参数课查看帮助文档;
命令:
jobs :查看当前有多少在后台运行的命令
&:运行程序放在后台
Ctrl+z 将一个正在前台运行的程序放到后台,并暂停
fg : 将后台运行的程序调度到前台
bg : 将一个再后台暂停的命令编程继续执行
具体指令及其参数查看帮助文档
nice 按用户指定的优先级运行进程
renice 改变正在运行进程的优先级
五、多进程编程的相关函数

多进程的资源调度机制


一、fork函数

函数头文件: #include<sys/types.h>
#include<unistd.h>
函数原型: pid_t fork(void);
函数返回值:
0 :子进程
>0 : 父进程
-1 : 出错
fork 函数:
用于从已经存在的进程中创建一个新的进程,新进程称为子进程,原进程称为父进程,子进程继承了父进程的整个进程的地址空间,包括进程上下文,代码段,进程堆栈,内存信息,打开的文件描述符,信号处理函数,进程优先级,进程组号,当前工作目录,根目录,资源限制,控制终端等。
子进程仅有自己的进程号,资源使用和计时器。
当子进程和父进程同时打开一个文件时,其子进程对文件的操作,父进程可见。
二,exec族函数
关于exec族函数的几点说明:
1,与fork函数不同的是,exec族函数提供了一种在进程中启动另一个程序执行的方法,根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段,代码段和堆栈段。在执行完之后,原进程的内容,除了进程号外,其他全部被替换了。
2,当进程认为自己 不能再为系统和用户做出任何贡献时就可以调用exec函数,让自己执行新的程序。在执行某个进程的同时想要执行另外一个程序,它就可以调用fork函数创建子进程,然后在子进程中调用exec函数。
exec族函数头文件:
#include<unistd.h>
exec族函数原型:

其中 l,v,e,p的含义:

三,exit函数 _exit函数


从图中可以看出,_exit 函数的作用是:直接使进程停止运行,清除其使用的内存空间,并清除其在内核的各种数据结构;exit 函数则在这些基础上做了一些小动作,在执行退出之前还加了若干道工序。exit() 函数与 _exit() 函数的最大区别在于exit()函数在调用exit 系统调用前要检查文件的打开情况,把文件缓冲区中的内容写回文件。也就是图中的“清理I/O缓冲”。
所需头文件: exit: #include<stdlib.h>
_exit: #include<unistd.h>
函数原型:exit: void exit(int status)
_exit: void _exit(int status)
函数传入值:status 是一个整型的参数,可以利用这个参数传递进程结束时的状态。一般来说,0表示正常结束;其他的数值表示出现了错误,进程非正常结束。在实际编程时,父进程可以利用wait 系统调用接收子进程的返回值,从而针对不同的情况进行不同的处理。
四,wait函数 waitpid函数
1,wait函数与waitpid函数说明:
wait函数用于使父进程(调度wait函数的进程)阻塞,知道子进程结束或者该进程接到了一个指定的信号为止。如果父进程没有子进程或者他的子进程已经结束,则wait函数会立即返回-1。
waitpid的作用和wait一样,单它不一定要等待第一个终止的子进程。实际上wait函数只是waitpid函数的一个特例。
2,wait函数和waitpid函数:


关于waitpid函数实例:
由于wait()函数的使用较为简单,在此仅以waitpid()为例进行讲解。本例中首先使用fork()创建一个子进程,然后让其子进程暂停5s(使用了sleep()函数)。接下来对原有的父进程使用waitpid()函数,并使用参数WNOHANG使该父进程不会阻塞。若有子进程退出,则waitpid()返回子进程号;若没有子进程退出,则waitpid()返回0,并且父进程每隔1s循环判断一次。该程序的流程图如图1所示。


Linux中用户上层是如何维护控制各进程的呢、这里就需要了解到进程组和会话的概念。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值