04_嵌入式Linux应用程序开发.ppt_第1页
04_嵌入式Linux应用程序开发.ppt_第2页
04_嵌入式Linux应用程序开发.ppt_第3页
04_嵌入式Linux应用程序开发.ppt_第4页
04_嵌入式Linux应用程序开发.ppt_第5页
已阅读5页,还剩62页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、嵌入式Linux应用程序开发,课程安排,Linux系统文件与I/O Linux系统多进程并发 Linux系统多线程并发 Linux系统网络通信,Linux一切皆文件:Linux上的任何事物都可以用一个文件代表,可以通过文件操作该事物 (1)普通文件( regular file ) (2)目录:包含了其他文件的名字以及指向与这些文件有关信息的指针 (3)设备文件(/dev):字符特殊文件、块特殊文件 (4)FIFO:用于进程间的通信,有时也将其称为命名管道 (5)符号连接(symbolic link):指向另一个文件 (6)套接口(socket):用于宿主机间网络通信,Linux文件,Linux

2、文件操作,1、Linux系统基本操作函数:open、close、read、write和ioctl 2、Linux对文件的操作基于打开的文件描述符,Linux文件描述符,1、linux内核是通过文件描述符区分和引用文件,文件描述符表示一个已打开的 文件 2、文件描述符为非负整数,保存了进程文件描述符表(已打开文件表)的索引 3、一个进程启动后,系统自动打开3个文件:标准输入、标准输出、标准出错, 对应文件描述符为: STDIN_FILENO(1)、STDOUT_FILENO(2)、STDERR_FILENO(3) 4、Linux上一个进程可打开的最大文件描述符值为1024,文件描述符实例,Lin

3、ux系统IO操作,1、Linux系统实现一整套文件处理函数,统一操作Linux上的文件:普通文件、网络socket文件、设备文件等 2、这些函数通过系统调方式实现,称为系统IO: open 打开或创建一个文件 creat 建立一个空文件 close 关闭一个文件 read 从文件读入数据 write 向文件写入一个数据 lseek 在文件中移动读写位置 unlink 删除一个文件 remove 删除一个文件本身 fcntl 控制一个文件属性,IO操作实例实现文件拷贝,课程安排,Linux系统文件与I/O Linux系统多进程并发 Linux系统多线程并发 Linux系统网络通信,操作系统将程序

4、读入内存,分配ID,管理程序的执行状态,形成进程,进程可以看一个正在执行的程序实例,有自己的地址空间和执行状态 进程作为构成系统的基本细胞,不仅是系统内部独立运行的实体,而且是独立竞争资源的基本实体 Linux是一个多进程的系统,进程之间具有并行性、互不干扰: 1、每一个进程都运行在各自独立的虚拟地址空间 2、即使一个进程发生异常,也不会影响其他进程 3、通过ps -el命令可以查看当前系统上运行的所有用户进程信息 进程是运行中的程序!,什么是进程,程序运行映像布局,1、内核空间与用户空间 Linux简化了分段机制,使得虚拟地址与线性地址总是一致,Linux的虚拟地址空间也为0 4G 最高的1

5、G字节(从虚拟地址0 xC0000000到0 xFFFFFFFF)供内核使用,称为“内核空间” 较低的3G字节(从虚拟地址0 x00000000到0 xBFFFFFFF)供各个进程使用,称为“用户空间”) 每个进程可以通过系统调用进入内核,Linux内核由系统内的所有进程共享 从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间,Linux上的进程,2、内核态与用户态 当进程执行系统调用而进入内核代码中运行时,我们就称进程处于内核运行态(或简称为内核态) 此时处理器处于特权级(高级),可以执行特权指令,不受其他进程干扰 当进程在执行用户自己的代码时,则称其处于用户运行态(用户态) 此时处理

6、器处于用户级(低级) 3、进程调度 在Linux中,每个进程在创建时都会被分配一个数据结构,称为进程控制块(Process Control Block)简称PCB,供系统调度和进程本身执行使用 调度时,Linux系统以分时复用机制调度多个进程,进程调度过程成为进程上下文切换(context switch):即将一个进程从运行状态退出,并运行另一个进程,Linux上的进程,进程调度,1、在Linux 操作系统中以PID唯一地标识一个进程 进程ID(PID)也被称作进程标识符,是一个非负的整数 进程ID从2开始,1一般为特殊进程init保留 2、Linux上的进程具备亲缘关系 PID为进程号,PP

7、ID为父进程号;init为所有进程的祖先,进程号(PID),ps -aux查看系统中的进程: D 不可中断睡眠 (通常是在IO操作) R 正在运行或可运行(在运行队列排队中) S 可中断睡眠 (在等待某事件完成) T Stopped, either by a job control signal or because it is being traced. W 正在换页(2.6.内核之前有效) X 死进程 (should never be seen) Z 僵尸,进程状态,进程与父进程ID,1、获取进程ID(PID) 2、获取父进程ID(PPID),创建进程,1、在shell中运行程序,shel

8、l派生一个子进程装载程序映像执行 2、也可以在程序中通过fork系统调用创建一个子进程,Fork结果,1、示例代码 2、运行结果 “fork done!”打印了2次!,Fork特点,1、fork创建得到的子进程直接克隆父进程的程序映像(映像一样但存放在2个独立的进程地址空间) 2、fork后得到2条程序运行路径:父进程与子进程运行路径 3、为了区分父进程运行路径与子进程运行路径,fork调用1次,返回2次 返回值大于0:父进程路径,返回值表示新建的子进程PID 返回值等于0:子进程路径,Fork使用,1、示例代码 2、执行结果,进程退出,1、主函数(main)中调用return语句,退出整个进

9、程 其他函数中调用return语句,只退出该函数 2、在程序中任何地方调用exit,退出整个进程 3、main的return返回值,和exit的status用来记录进程退出状态,通常0表示正常退出,僵尸与孤儿,1、一个进程退出之后,该进程并不马上就完全消失,而是变成僵尸进程(Zombie) 僵尸进程仅仅在系统中记录了进程退出状态,等待善后处理 子进程退出产生僵尸进程:,僵尸与孤儿,2、僵尸进程太多会影响系统性能(进程退出状态一直未被回收) 一般采用谁创建则谁负责回收原则,由父进程回收子进程 3、如果父进程在子进程退出之间就消亡了,会产生什么想象? 子进程将成为孤儿进程,init自动成为子进程的

10、继父 父进程退出,子进程成为孤儿:,进程同步,1、孤儿进程太多也会影响系统性能,所有孤儿进程退出状态都需要init去回收 2、一般情况下,由父进程负责回收子进程,这就涉及父子进程同步 通过wait/waitpid系统调用实现父子进程同步 status保存子进程退出状态,返回值表示结束的子进程ID wait使父进程挂起等待,直到任何一个子进程结束并回收返回 waitpid可以实现等待指定pid的子进程结束 waitpid的option参数设为WNOHANG,不阻塞等待没有子进程结束则返回0,进程退出状态,1、Wait/waitpid获得子进程退出时的状态(status),退出状态包含:进程退出原

11、因和返回值(低8位) 2、系统定义了一些宏函数用于检测进程退出状态 (1)、WIFEXITED(status)如果子进程正常结束,宏非零 (2)、WEXISTSTATUS(status):WIFEXITED非零,宏返回进程退出码低8位,进程同步意义,1、进程创建后,子进程先运行还是父进程先运行依赖于系统调用机制 Linux系统采用优先级、先来先服务、分时复用等排队调度机制 2、两个进程协调以安排好地次序依次执行,称为进程同步: 进程间同步有多种方法,其中用wait是一种方法 wait一般只用于父子进程之间进行同步 而非父子关系进程间同步,需要用到进程间通讯机制 3、父子进程同步没做好,会影响系

12、统性能 如果子进程先于父进程退出,形成僵尸进程 如果父进程先于子进程退出,形成孤儿进程.,exec加载新映像,1、子进程成为父进程的复制品意义并不大 2、exec函数族提供了一个在进程中启动另一个可执行文件的方法 将新的可执行文件映象来覆盖调用进程的映象,执行新程序,execve是系统调用,其它都是在此基础上封装的库函数,exec示例,为了让旧映像也能正常执行,通常的做法是在子进程中执行exec,并且在父进程中回收子进程退出状态,system函数,System函数专门用于执行一个shell命令 System内部调用fork产生子进程,子进程调用/bin/sh 执行参数comand所代表的命令

13、父进程调用waitpid等待命令执行结束,所以命令执行完返回原调用的进程,多进程的好处,1、多进程可以使用并发操作,即CPU同时执行多于1个任务,提高处理效率 2、例如:需要备份多个文件时,如果1个个地顺序备份,效率低下;可以使用成多进程并发实现,提高效率 3、实现方法:为每个文件重建1个子进程执行备份任务,1、IPC是指能在两个进程间进行数据交换的机制 2、进程运行于独立的地址空间,因此两个进程不能直接交换数据,必须通过一定机制来完成 3、IPC的机制的作用如下: (1)为多进程提供资源共享机制 (2)提供进程之间的同步机制:如1个进程先写,另一个进程再读 (2)提供多进程访问共享资源的互斥

14、机制:如多个进程同时向一个地方写,IPC的概念,1、无名管道(pipe),命名管道(fifo) 无名管道可用于具有亲缘关系进程间通信 有名管道除了具有管道的功能外,还允许无亲缘关系进程间通信 2、信号(signal) 信号是软件层次上对中断机制的一种模拟,用于通知进程有某事件发生 3、消息队列 消息队列是消息的缓存表,消息队列使得通信信息量可以更大 4、共享内存 多个进程可以访问同一块内存空间,数据交互更加直接 但需要同步/互斥机制,IPC的种类,5、信号量,信号量集 主要作为进程间通信的同步和互斥手段. 6、套接字(socket) 主要用于网络通信,不同主机上的进程间通信 当然也可以用于同一

15、主机不同进程间的通信 如进程架构的GUI往往就是用socket实现进程间通信,IPC的种类,1、无名管道称为PIPE,通常用于父子(亲缘关系)进程间数据通讯 2、Shell中|操个作符就是通过管道实现的 将上一个命令的输出,通过管道输入到下一个命令 3、 PIPE建立后利用I/O操作实现共享数据读写 PIPE只存在于内存中,并没有相应文件名,所以叫无名管道,管道PIPE概念,1、创建无名管道(PIPE) int pipe (int fd2) 返回0,表示成功;fd0返回管道出口,fd1返回管道入口; fd0, fd1通过文件描述符来表示pipe的出口与入口 进程可以从fd0读,并向fd1写。

16、2、管道销毁 close(fd0) 关闭读端 close(fd1) 关闭写端,PIPE创建与销毁,1、通过read/write实现对PIPE的读写: (1)read(fd0):从PIPE出口读 (2)read(fd1), 向PIPE入口写 2、在单个进程中,PIPE没什么实际意义,PIPE主要用在亲缘进程间通讯 (1)先创建一个管道PIPE (2)通过fork()创建子进程 (3)子进程会复制父进程创建的管道PIEP (4)父子进程通过读、写管道PIPE实现数据通讯,PIPE进程间通讯,1、创建管道,PIPE通讯实例,2、子进程写管道,PIPE通讯实例,3、父进程读管道,PIPE通讯实例,课程

17、安排,Linux系统文件与I/O Linux系统多进程并发 Linux系统多线程并发 Linux系统网络通信,1、进程是系统中程序执行和资源分配的基本单位. (1)、每个进程都拥有自己的数据段,代码段和堆栈段,所以进程在上下文切换时开销较大. (2)、程间交换信息需要利用内核提供的特殊的通信手段(IPC) 2、为了支持程序多道执行路径并进一步减少开销,提高共享数据的效率,进程演化出另一个概念-线程 (1)线程是一个进程内的基本调度单位,一个进程内的多个线程是在共享进程内存空间中并发的多道执行路径,它们共享进程资源. (2)线程又成为轻量级进程,线程的来由,1、进程是一个应用程序独立运行单位,而

18、线程不能独立存在,必须由在一个进程创建 2、同一个进程创建的所有线程之间共享创建进程的空间 3、当一个线程修改一个全局变量后,另一个线程也能直接访问得到这个值 4、多线程并发修改某个全局变量,必须要进行加锁保护,以便互斥访问,线程的特点,1、Linux系统下的多线程遵循POSIX线程接口 ,所以被称为pthread 2、pthread是目前Linux平台上使用最为广泛的线程库,编译时加上 -lpthread选项,链接线程库 3、Linux内核并不支持真正意义上的线程,LinuxThreads是用与普通进程具有同样内核调度视图的轻量级进程来实现线程支持 4、Linux平台的嵌入式并发应用中,很多

19、时候采用多线程架构,嵌入式Linux也支持pthread库,Linux上的线程,1、函数原型 2、参数说明 (1)thread用于返回线程标识符 (2)attr 用于传入线程属性 (3)start_routine是线程开始执行时调用的函数名 (4)arg为传递给start_routine的参数,线程创建,3、使用说明: (1)创建线程实际上就是确定该线程启动时调用的入口函数 (2)pthread_create过后,会自动使线程成为可执行 (3)pthread_create返回后,线程自动进入就绪态,start_routine将被CPU调度执行. 4、线程中,通过phread_self可以获得自

20、身线程ID,线程创建,线程创建示例,1、主进程结束之后,进程上的所有线程也结束 2、线程入口函数执行完毕,线程自动结束 3、在线程中不能调用exit函数退出,exit会退出整个主进程 4、线程的退出函数是phread_exit,只会退出线程自身 线程退出后,需要回收退出状态占用的资源!,线程退出,当线程为非死循环执行的任务时,先分离自己,实现资源自动回收,线程回收示例,1、在多个线程间共享的资源,访问时必须加以保护,确保同一时间只有一个线程访问数据 2、可以通过pthread_mutex(互斥锁)实现互斥保护: (1)在访问共享资源前对互斥锁加锁,在访问完成后互斥锁解锁 (2)对互斥锁加锁以后,任何其他试图再次加锁的线程将被阻塞直到当前线程解锁 (3)多个等待同一互斥锁的线程会阻塞在互斥锁等待队列,拥有锁资源的线程解锁后,只有一个线程编程进入就绪状态,其他线程继续阻塞,等待下一次解锁,多线程互斥访问,1、初始化一个互斥锁 pthread_mutex_init() /更为简便的初始化方法 static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INI

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论