嵌入式Linux C语言开发 教学课件 ppt 华清远见嵌入式学院 曾宏安 第6章 嵌入式Linux进程和线程编程

上传人:E**** 文档编号:89409269 上传时间:2019-05-24 格式:PPT 页数:81 大小:614KB
返回 下载 相关 举报
嵌入式Linux C语言开发 教学课件 ppt 华清远见嵌入式学院 曾宏安 第6章 嵌入式Linux进程和线程编程_第1页
第1页 / 共81页
嵌入式Linux C语言开发 教学课件 ppt 华清远见嵌入式学院 曾宏安 第6章 嵌入式Linux进程和线程编程_第2页
第2页 / 共81页
嵌入式Linux C语言开发 教学课件 ppt 华清远见嵌入式学院 曾宏安 第6章 嵌入式Linux进程和线程编程_第3页
第3页 / 共81页
嵌入式Linux C语言开发 教学课件 ppt 华清远见嵌入式学院 曾宏安 第6章 嵌入式Linux进程和线程编程_第4页
第4页 / 共81页
嵌入式Linux C语言开发 教学课件 ppt 华清远见嵌入式学院 曾宏安 第6章 嵌入式Linux进程和线程编程_第5页
第5页 / 共81页
点击查看更多>>
资源描述

《嵌入式Linux C语言开发 教学课件 ppt 华清远见嵌入式学院 曾宏安 第6章 嵌入式Linux进程和线程编程》由会员分享,可在线阅读,更多相关《嵌入式Linux C语言开发 教学课件 ppt 华清远见嵌入式学院 曾宏安 第6章 嵌入式Linux进程和线程编程(81页珍藏版)》请在金锄头文库上搜索。

1、,嵌入式Linux进程和线程编程,www.embedu.org,课程目标,进程相关的基本概念 Linux进程的创建 Linux进程的管理和守护进程 Linux进程间通信的方式 Linux中线程创建和退出 Linux中线程间的同步和互斥,www.embedu.org,本章内容,6.1 Linux进程概述 6.2 Linux进程控制相关API 6.3 ARM Linux进程间通信 6.4 ARM Linux线程相关API 6.5 Linux守护进程 本章小结,www.embedu.org,6.1 Linux进程概述,6.1.1 进程描述符及任务结构 6.1.2 进程的调度 6.1.3 Linux中

2、的线程,www.embedu.org,6.1.1 进程描述符及任务结构,进程概念 进程的概念首先在20世纪60年代初期由MIT的Multics系统和IBM的TSS/360系统中引入的。 (1)进程是一个独立的可调度的活动(E.Cohen,D.Jofferson)。 (2)进程是一个抽象实体,当它执行某个任务时,将要分配和释放各种资源(P.Denning)。 (3)进程是可以并行执行的计算部分(S.E.Madnick,J.T.Donovan)。 进程和程序有本质的区别:程序是静态的,它是一些保存在磁盘上的指令的有序集合,没有任何执行的概念;而进程是一个动态的概念,它是程序执行的过程,包括了动态创

3、建、调度和消亡的整个过程,它是程序执行和资源管理的最小单位。,www.embedu.org,6.1.1 进程描述符及任务结构,Linux中进程描述符 进程不但包括程序的指令和数据,而且包括程序计数器和CPU的所有寄存器以及存储临时数据的进程堆栈。 内核把进程存放在任务队列(task list)的双向循环链表中,其中链表的每一项都是类型为task_struct,称为进程描述符的结构,该结构定义在中 。,www.embedu.org,6.1.1 进程描述符及任务结构,Linux中进程描述符 Linux通过slab分配器分配task_struct结构,它实际上是一个栈,其栈顶(向上增长的栈)或栈底(

4、向下增长的栈)中有一个thread info结构,其中的task指针指向task_struct。 下面详细讲解task_struct结构中最为重要的两个域:state和pid。,www.embedu.org,6.1.1 进程描述符及任务结构,Linux中进程描述符 (1)进程状态,运行 (TASK_RUNNING) 可中断 (TASK_INTERUPTIBLE) 不可中断 (TASK_UNINTERUPTIBLE) 僵死 (TASK_ZOMBIE) 停止 (TASK_STOPPED),www.embedu.org,6.1.1 进程描述符及任务结构,Linux中进程描述符 (2)任务标识 Lin

5、ux内核通过惟一的进程标识值PID来标识每个进程。PID是一个非负数,它实际上是一个短整型数据,也就是说它最大值为32767。读者可以查看/proc/sys/kernel/pid_max来确定该系统的进程数上限。一般来说,32767对于很多桌面系统已经足够,但是对于大型服务器,就必须修改这个上限。,www.embedu.org,6.1.1 进程描述符及任务结构,进程的创建、执行和终止 (1)进程的创建和执行 许多操作系统都提供的是产生进程的机制,也就是首先在新的地址空间里创建进程、读入可执行文件,最后再开始执行。 首先,fork()通过拷贝当前进程的内容创建一个子进程,子进程与父进程的区别仅仅

6、在于不同的PID、PPID和其他一些资源。 exec函数负责读取可执行文件并将其载入地址空间开始运行。,www.embedu.org,6.1.1 进程描述符及任务结构,进程的创建、执行和终止 (2)进程的终止 进程终结也需要做很多繁琐的收尾工作,系统必须保证进程所占用的资源回收,并通知父进程。 Linux首先把终止的进程设置为僵死状态,这个时候,进程无法投入运行了。它的存在只为父进程提供信息,申请死亡。父进程得到信息后,开始调用wait (),子进程占用的资源被全部释放。,www.embedu.org,6.1.2 进程的调度,Linux中进程调度概述 Linux中进程调度算法,www.embe

7、du.org,Linux中进程调度概述,进程调度是指确定CPU当前执行哪个进程。Linux进程调度策略是以优先级调度为基础的,即优先运行优先级最高的进程。根据优先级的范围,可以把进程分为实时进程(这里的实时是软实时)和普通进程。实时进程优先级高于普通进程,并由特定的调度策略来保证它们的(软)实时性。 内核中的默认配置是:进程优先级在0139,其中实时进程占用099,一般进程占用100139。 在调度时,系统总是首先选取具有最高优先级的并且拥有活跃进程的进程组,然后进行相同优先级下的进程调度。,www.embedu.org,Linux中进程调度算法,Linux 2.6内核中实现了一个O(1)的调

8、度算法,也就是说每一次调度所需要的时间与该CPU内的总进程数无关 。 Linux中每个运行队列都有两个优先级数组,一个活跃的和一个过期的。优先级数组在kernel/sched.c中被定义,它是prio_array类型的结构体。,struct prio_array unsigned int nr_active; /* 当前活跃的进程总数 */ unsigned long bitmapBITMAP_SIZE; /* 活跃进程的位图 */ struct list_head queueMAX_PRIO; /* 各个优先级队列的头指针组成的数组*/ ;,www.embedu.org,6.1.3 Linu

9、x中的线程,线程机制是现代编程技术中常用的一种抽象,该机制提供了在同一程序内共享内存地址空间运行的一组线程。这些线程可以共享打开的文件和其他资源等。 Linux中实现线程的机制非常独特。从内核的角度来说,它并没有线程这个概念。Linux把线程都当作进程来实现,仅仅将其视为使用某些共享资源的进程。每个线程都用有惟一隶属于自己的task_struct,所以在内核中,它看起来就像一个普通的进程 。,www.embedu.org,6.2 Linux进程控制相关API,进程的创 建 fork (1)fork函数说明 执行一次却返回两个值,父进程的返回值是子进程的进程号,而子进程则返回0 。 (2)for

10、k函数语法 fork函数的语法格式如下所示。 头文件 #include / 提供类型pid_t的定义 #include 函数原型 pid_t fork(void); 函数返回值 0:子进程 子进程ID(大于0的整数):父进程 -1:出错,www.embedu.org,6.2 Linux进程控制相关API,进程的创 建 (3)fork函数调用实例 /*调用fork函数,其返回值赋给result*/ int result = fork(); /*通过result的值来判断fork函数的返回情况,首先进行出错处理*/ if(result = -1) perror(“fork“); exit(-1);

11、 /*返回值为0代表子进程*/ else if(result = 0) /*子进程相关语句*/ /*返回值大于0代表父进程*/ else /*父进程相关语句*/ ,www.embedu.org,6.2 Linux进程控制相关API,进程的创 建 exec函数族 (1)exec函数族说明 fork函数是用于创建一个子进程,该子进程几乎拷贝了父进程的全部内容。 exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的路径和文件名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新的内容替换了。另外,这里的可执行

12、文件既可以是二进制文件,也可以是Linux下任何可执行的脚本文件。,www.embedu.org,6.2 Linux进程控制相关API,进程的创 建 exec函数族 (2)exec函数族语法 实际上,在Linux中并没有exec()函数,而是以exec开头的函数族,它们之间语法有细微差别。 exec函数族语法格式如下所示。 头文件 #include 函数原型 int execl(const char *path, const char *arg, .); int execv(const char *path, char *const argv); int execle(const char *

13、path, const char *arg, ., char *const envp); int execve(const char *path, char *const argv, char *const envp); int execlp(const char *file, const char *arg, .); int execvp(const char *file, char *const argv); 函数返回值 出错1:-1,www.embedu.org,6.2 Linux进程控制相关API,进程的创 建 exec函数族 (2)exec函数族语法,www.embedu.org,6

14、.2 Linux进程控制相关API,进程的创 建 exec函数族 (3)exec函数组调用实例 使用execlp函数,采用逐个列举方式,并且使用系统默认的环境变量。 使用execl函数时需要给出完整的文件路径来查找对应的可执行文件。,if(fork()=0) /*调用execlp函数,这里相当于调用了“ls -l”命令*/ if(execlp(“ls“,“ls“,“-l“,NULL)0) perror(“execlp error!“); ,/*调用execl函数,注意这里要给出ls程序所在的完整路径*/ if(execl(“/bin/ls“,“ls“,“-l“,NULL)0) perror(“

15、execl error!“);,www.embedu.org,6.2 Linux进程控制相关API,进程的创 建 exec函数族 (3)exec函数组调用实例 使用execle时可以将环境变量添加到新建的子进程中去 使用execve函数时,通过构造指针数组的方式来传递参数,注意参数列表一定要以NULL作为结尾标识符。,/*命令参数列表,必须以NULL结尾*/ char *envp=“PATH=/tmp“,“USER=sunq“,NULL; /*调用execle函数,注意这里也要指出env的完整路径*/ if(execle(“/bin/env“,“env“,NULL,envp)0) perror

16、(“execle error!“);,/*命令参数列表,必须以NULL结尾*/ char *arg=“env“,NULL; char *envp=“PATH=/tmp“,“USER=sunq“,NULL; if(execve(“/bin/env“,arg,envp)0) perror(“execve error!“);,www.embedu.org,6.2 Linux进程控制相关API,进程的创 建 exit和_exit (1)exit和_exit函数说明 exit和_exit函数都是用来终止进程的。当程序执行到exit或_exit时,进程会无条件地停止剩下的所有操作,清除包括PCB在内的各种数据结构,并终止本进程的运行。 exit()函数与_exit()函数的区别就在于exit()函数在调用exit系统调用之前要检查进程中文件的打开情况,把文件缓冲区中的内容写回文件。 如果用_exit()函数直接将进程关闭,缓冲区中的数据就会丢失。因此,若想保证数据的完整性,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号