第3章 嵌入式Linux多任务编程

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

许多操作系统都提供的是产生进程的机制,也就是首先在新的地址空间 里创建进程、读入可执行文件,最后再开始执行。Linux中进程的创建很 特别,它把上述步骤分解到两个单独的函数中取执行:fork()和exec函数 族。首先,fork()通过拷贝当前进程创建一个子进程,子进程与父进程的 区别仅仅在于不同的PID、PPID和某些资源及统计量。exec函数族负责 读取可执行文件并将其载入地址空间开始运行。 进程终结也需要做很多繁琐的收尾工作,系统必须保证进程所占用的资 源回收,并通知父进程。Linux首先把终止的进程设置为僵尸状态,这个 时候,进程无法投入运行了,它的存在只为父进程提供信息,申请死亡 。父进程得到信息后,开始调用wait函数族,最终赐死子进程,子进程 占用的所有资源被全部释放。

3.1.2 进程

进程的种类: 交互式进程 批处理进程 实时进程
进程和程序是有本质区别的:


程序是静态的一段代码,是一些保存在非易失性存储器的指令的有序集 合,没有任何执行的概念;而进程是一个动态的概念,它是程序执行的 过程,包括了动态创建、调度和消亡的整个过程,它是程序执行和资源 管理的最小单位。
30
3.2 进程控制编程


3.2.2 Linux守护进程
改变当前目录为根目录

通常的做法是让“/”作为守护进程的当前工作目录 。 使用fork创建的子进程继承了父进程的当前工作目录。由于在进程运行 过程中,当前目录所在的文件系统是不能卸载的,这对以后的使用会 造成诸多的麻烦(比如进入单用户模式)。

找不到文件或路径,此时errno被设置为ENOENT; 数组argv和envp忘记用NULL结束,此时errno被设置为EFAULT; 没有对应可执行文件的运行权限,此时errno被设置为EACCES。
18
3.2 进程控制编程

3.2.1 进程编程基础

exit()和_exit()

exit()和_exit函数语法:

2
本章课程:

3.1 Linux下多任务机制的介绍 3.2 进程控制编程 3.3 实验内容 3.4 小结 3.5 思考与练习
3
3.1 Linux下多任务机制的介绍


多任务处理是指用户可以在同一时间内运行多个 应用程序,每个应用程序被称作一个任务。Linux 就是一个支持多任务的操作系统,比起单任务系 统它的功能增强了许多。 当多任务操作系统使用某种任务调度策略允许两 个或更多进程并发共享一个处理器时,事实上处 理器在某一时刻只会给一件任务提供服务。因为 任务调度机制保证不同任务之间的切换速度十分 迅速,因此给人多个任务同时运行的错觉。多任 务系统中有3个功能单位:任务、进程和线程。
31
3.2 进程控制编程


3.2.2 Linux守护进程
重设文件权限掩码
13
3.1 Linux下多任务机制的介绍

3.1.3 线程

线程的种类 用户级线程 轻量级进程 内核线程
14
3.2 进程控制编程

3.2.1 进程编程基础


fork()
fork()函数用于从已存在的进程中创建一个新进程。新进程称为子进程,而 原进程称为父进程。使用fork()函数得到的子进程是父进程的一个复制品, 它从父进程处继承了整个进程的地址空间,包括进程上下文、代码段、进 程堆栈、内存信息、打开的文件描述符、信号控制设定、进程优先级、进 程组号、当前工作目录、根目录、资源限制和控制终端等,而子进程所独 有的只有它的进程号、资源使用和计时器等。
嵌入式应用程序设计
第3章 嵌入式Linux多任务编程
课程安排:
第1章 搭建嵌入式Linux开发环境 第2章 嵌入式文件I/O编程 第3章 嵌入式Linux多任务编程 第4章 嵌入式Linux进程间通行 第5章 嵌入式Linux多线程编程 第6章 嵌入式Linux网络编程 第7章 Qt图形编程 第8章 嵌入式Linux设备驱动编程 第9章 Qt聊天项目设计

进程的终止:

11
3.1 Linux下多任务机制的介绍

3.1.2 进程

进程的内存结构
12
3.1 Linux下多任务机制的介绍

3.1.3 线程


线程的概念 它是进程内独立的一条运行路线,处理器调度的最小单元,也可 以称为轻量级进程。线程可以对进程的内存空间和资源进行访问 ,并与同一进程中的其他线程共享。因此,线程的上下文切换的 开销比创建进程小得多。 线程与进程间的关系
7
3.1 Linux下多任务机制的介绍

3.1.2 进程

主要的进程标识:


进程号(Process Idenity Number,PID) PID惟一地标识一个进程 父进程号(parent process ID,PPID) 指向当前进程的父进程
8
3.1 Linux下多任务机制的介绍

3.1.2 进程
21
3.2 进程控制编程

3.2.1 进程编程基础

wait()和waitpid()


wait()函数是用于使父进程(也就是调用wait()的进程)阻塞,直 到一个子进程结束或者该进程接到了一个指定的信号为止。如果 该父进程没有子进程或者他的子进程已经结束,则wait()就会立即 返回。 wait函数语法:
19
3.2 进程控制编程

3.2.1 进程编程基础

exit()和_exit()的执行过程
20
3.2 进程控制编程

3.2.1 进程编程基础

exit()和_exit()的区别

_exit()函数的作用最为简单:直接使进程停止运行,清除其使用 的内存空间,并销毁其在内核中的各种数据结构; exit()函数则在这些基础上作了一些包装,在执行退出之前加了若 干道工序。 exit()函数在调用exit系统调用之前要检查文件的打开情况,把文 件缓冲区中的内容写回文件,就是图中的"清理I/O缓冲"一项。
28
3.2 进程控制编程


3.2.2 Linux守护进程
在子进程中创建新会话


进程组 进程组是一个或多个进程的集合。进程组由进程组ID来惟一标识。 除了进程号(PID)之外,进程组ID也是一个进程的必备属性。 每个进程组都有一个组长进程,其组长进程的进程号等于进程组ID 。且该进程ID不会因组长进程的退出而受到影响。 会话期 会话组是一个或多个进程组的集合。通常,一个会话开始于用户登 录,终止于用户退出,在此期间该用户运行的所有进程都属于这个 会话期

fork()函数语法:
15
3.2 进程控制编程

3.2.1 进程编程基础

exec函数族

fork()函数是用于创建一个子进程,该子进程几乎拷贝了父进程的 全部内容,但是,这个新创建的进程如何执行呢?这个exec函数 族就提供了一个在进程中启动另一个程序执行的方法。

exec函数族成员函数语法:

wait()和waitpid()

waitpid函数语法:
24
3.2 进程控制编程

3.2.1 进程编程基础

wait()和waitpid()

waitpid实例:
开始
fork()
返回值 = 0
fork()返回值
返回值>0 父进程调用 waitpid()
子进程暂停5s waitpid() 返回值 子进程退出 返回值<0(出错) 返回值 = 子进程号 捕获子进程退出
4
3.1 Linux下多任务机制的介绍

3.1.1 任务

任务是一个逻辑概念,指由一个软件完成的活动,或者是一系列共 同达到某一目的的操作。通常一个任务是一个程序的一次运行,一 个任务包含一个或多个完成独立功能的子任务,这个独立的子任务 是进程或者是线程。 任务、进程和线程之间的关系 :

5
3.1 Linux下多任务机制的介绍
29
3.2 进程控制编程


3.2.2 Linux守护进程
在子进程中创建新会话


setsid()函数作用: setsid()函数用于创建一个新的会话,并担任该会话组的组长。调用 setsid()有下面的3个作用。 让进程摆脱原会话的控制。 让进程摆脱原进程组的控制。 让进程摆脱原控制终端的控制。 setsid()函数格式:

3.1.2 进程


进程是指一个具有独立功能的程序在某个数据集合上的一次动态执 行过程,它是系统进行资源分配和调度的基本单元。一次任务的运 行可以并发激活多个进程,这些进程相互合作来完成该任务的一个 最终目标。 进程的特性

并发性 动态性 交互性 独立性 异步性
6
3.1 Linux下多任务机制的介绍
22
3.2 进程控制编程

3.2.1 进程编程基础

wait()和waitpid()

waitpid()的作用和wait()一样,但它并不一定要等待第一个终止的子进程 ,它还有若干选项,如可提供一个非阻塞版本的wait()功能,也能支持作 业控制
23
3.2 进程控制编程

3.2.1 进程编程基础

进程状态

运行状态 可中断的阻塞状态 不可中断的阻塞状态 可终止的阻塞状态 暂停状态 跟踪状态 僵尸状态 僵尸撤销状态
9
3.1 Linux下多任务机制的介绍

3.1.2 进程

进程状态转换关系:
10
3.1 Linux下多任务机制的介绍

3.1.2 进程

进程的创建和执行:
父进程暂停5s 返回值 = 0
结束
25
3.2 进程控制编程

3.2.2 Linux守护进程


源自文库

守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务 进程。它是一个生存期较长的进程,通常独立于控制终端并且周期 性的执行某种任务或等待处理某些发生的事件 守护进程常常在系统引导装入时启动,在系统关闭时终止 Linux系统有很多守护进程,大多数服务都是用守护进程实现的 在Linux中,每一个系统与用户进行交流的界面称为终端,每一个 从此终端开始运行的进程都会依附于这个终端,这个终端就称为这 些进程的控制终端,当控制终端被关闭时,相应的进程都会被自动 关闭。 守护进程能够突破这种限制,它从被执行开始运转,直到整个系统 关闭才会退出。如果想让某个进程不因为用户或终端或其他的变化 而受到影响,就必须把这个进程变成一个守护进程。
26
3.2 进程控制编程


3.2.2 Linux守护进程
编写守护进程

创建子进程,父进程退出 在子进程中创建新会话 改变当前目录为根目录 重设文件权限掩码 关闭文件描述符
27
3.2 进程控制编程


3.2.2 Linux守护进程
创建子进程,父进程退出



这是编写守护进程的第一步。由于守护进程是脱离控制终端的,因此 ,完成第一步后就会在shell终端里造成一种程序已经运行完毕的假象 。之后的所有工作都在子进程中完成,而用户在shell终端里则可以执 行其他的命令,从而在形式上做到了与控制终端的脱离。 由于父进程已经先于子进程退出,会造成子进程没有父进程,从而变 成一个孤儿进程。在Linux中,每当系统发现一个孤儿进程,就会自动 由1号进程(也就是init进程)收养它,这样,原先的子进程就会变成 init进程的子进程了。 实例: pid = fork(); if (pid > 0) { exit(0); /*父进程退出*/ }


环境变量的使用

exec函数族可以默认系统的环境变量,也可以传入指定的环境 变量。这里,以“e”(Enviromen)结尾的两个函数execle、 execve就可以在envp[]中指定当前进程所使用的环境变量
17
3.2 进程控制编程

3.2.1 进程编程基础

exec函数执行失败,常见原因:
16
3.2 进程控制编程

3.2.1 进程编程基础

exec函数族使用区别

可执行文件查找方式

表中的前四个函数的查找方式都是完整的文件目录路径,而最 后两个函数(以p结尾的函数)可以只给出文件名,系统就会自动 从环境变量“$PATH”所指出的路径中进行查找。

参数表传递方式
两种方式:逐个列举、将所有参数整体构造指针数组传递 以函数名的第五位字母来区分的,字母为“l”(list)的表示逐个 列举的方式,其语法为char *arg;字母为“v”(vertor)的表示将 所有参数整体构造指针数组传递,其语法为*const argv[]
相关文档
最新文档