收藏 分享(赏)

04_嵌入式Linux应用程序开发.ppt

上传人:hyngb9260 文档编号:8314034 上传时间:2019-06-19 格式:PPT 页数:67 大小:1.74MB
下载 相关 举报
04_嵌入式Linux应用程序开发.ppt_第1页
第1页 / 共67页
04_嵌入式Linux应用程序开发.ppt_第2页
第2页 / 共67页
04_嵌入式Linux应用程序开发.ppt_第3页
第3页 / 共67页
04_嵌入式Linux应用程序开发.ppt_第4页
第4页 / 共67页
04_嵌入式Linux应用程序开发.ppt_第5页
第5页 / 共67页
点击查看更多>>
资源描述

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

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

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

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

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

7、s -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中运行程序,shell派生一个子进程装载程序映像执行2、也可以在程序中通过fork系

8、统调用创建一个子进程,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语句,退出整个进程其他函数中调用return语句,只退出该函数2、在程序中任何地方调用exit,

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

10、态都需要init去回收2、一般情况下,由父进程负责回收子进程,这就涉及父子进程同步通过wait/waitpid系统调用实现父子进程同步status保存子进程退出状态,返回值表示结束的子进程IDwait使父进程挂起等待,直到任何一个子进程结束并回收返回waitpid可以实现等待指定pid的子进程结束waitpid的option参数设为WNOHANG,不阻塞等待没有子进程结束则返回0,进程退出状态,1、Wait/waitpid获得子进程退出时的状态(status),退出状态包含:进程退出原因和返回值(低8位)2、系统定义了一些宏函数用于检测进程退出状态 (1)、WIFEXITED(status)如

11、果子进程正常结束,宏非零 (2)、WEXISTSTATUS(status):WIFEXITED非零,宏返回进程退出码低8位,进程同步意义,1、进程创建后,子进程先运行还是父进程先运行依赖于系统调用机制Linux系统采用优先级、先来先服务、分时复用等排队调度机制2、两个进程协调以安排好地次序依次执行,称为进程同步:进程间同步有多种方法,其中用wait是一种方法wait一般只用于父子进程之间进行同步而非父子关系进程间同步,需要用到进程间通讯机制3、父子进程同步没做好,会影响系统性能如果子进程先于父进程退出,形成僵尸进程如果父进程先于子进程退出,形成孤儿进程.,exec加载新映像,1、子进程成为父进

12、程的复制品意义并不大2、exec函数族提供了一个在进程中启动另一个可执行文件的方法将新的可执行文件映象来覆盖调用进程的映象,执行新程序,execve是系统调用,其它都是在此基础上封装的库函数,exec示例,为了让旧映像也能正常执行,通常的做法是在子进程中执行exec,并且在父进程中回收子进程退出状态,system函数,System函数专门用于执行一个shell命令System内部调用fork产生子进程,子进程调用/bin/sh 执行参数comand所代表的命令父进程调用waitpid等待命令执行结束,所以命令执行完返回原调用的进程,多进程的好处,1、多进程可以使用并发操作,即CPU同时执行多于

13、1个任务,提高处理效率2、例如:需要备份多个文件时,如果1个个地顺序备份,效率低下;可以使用成多进程并发实现,提高效率3、实现方法:为每个文件重建1个子进程执行备份任务,1、IPC是指能在两个进程间进行数据交换的机制2、进程运行于独立的地址空间,因此两个进程不能直接交换数据,必须通过一定机制来完成3、IPC的机制的作用如下: (1)为多进程提供资源共享机制(2)提供进程之间的同步机制:如1个进程先写,另一个进程再读(2)提供多进程访问共享资源的互斥机制:如多个进程同时向一个地方写,IPC的概念,1、无名管道(pipe),命名管道(fifo) 无名管道可用于具有亲缘关系进程间通信 有名管道除了具

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

15、2、Shell中|操个作符就是通过管道实现的将上一个命令的输出,通过管道输入到下一个命令3、 PIPE建立后利用I/O操作实现共享数据读写PIPE只存在于内存中,并没有相应文件名,所以叫无名管道,管道PIPE概念,1、创建无名管道(PIPE) int pipe (int fd2) 返回0,表示成功;fd0返回管道出口,fd1返回管道入口; fd0, fd1通过文件描述符来表示pipe的出口与入口 进程可以从fd0读,并向fd1写。2、管道销毁 close(fd0) 关闭读端 close(fd1) 关闭写端,PIPE创建与销毁,1、通过read/write实现对PIPE的读写:(1)read(f

16、d0):从PIPE出口读(2)read(fd1), 向PIPE入口写2、在单个进程中,PIPE没什么实际意义,PIPE主要用在亲缘进程间通讯(1)先创建一个管道PIPE(2)通过fork()创建子进程(3)子进程会复制父进程创建的管道PIEP(4)父子进程通过读、写管道PIPE实现数据通讯,PIPE进程间通讯,1、创建管道,PIPE通讯实例,2、子进程写管道,PIPE通讯实例,3、父进程读管道,PIPE通讯实例,课程安排,Linux系统文件与I/O Linux系统多进程并发 Linux系统多线程并发 Linux系统网络通信,1、进程是系统中程序执行和资源分配的基本单位. (1)、每个进程都拥有

17、自己的数据段,代码段和堆栈段,所以进程在上下文切换时开销较大. (2)、程间交换信息需要利用内核提供的特殊的通信手段(IPC)2、为了支持程序多道执行路径并进一步减少开销,提高共享数据的效率,进程演化出另一个概念-线程 (1)线程是一个进程内的基本调度单位,一个进程内的多个线程是在共享进程内存空间中并发的多道执行路径,它们共享进程资源. (2)线程又成为轻量级进程,线程的来由,1、进程是一个应用程序独立运行单位,而线程不能独立存在,必须由在一个进程创建2、同一个进程创建的所有线程之间共享创建进程的空间3、当一个线程修改一个全局变量后,另一个线程也能直接访问得到这个值4、多线程并发修改某个全局变

18、量,必须要进行加锁保护,以便互斥访问,线程的特点,1、Linux系统下的多线程遵循POSIX线程接口 ,所以被称为pthread2、pthread是目前Linux平台上使用最为广泛的线程库,编译时加上-lpthread选项,链接线程库3、Linux内核并不支持真正意义上的线程,LinuxThreads是用与普通进程具有同样内核调度视图的轻量级进程来实现线程支持4、Linux平台的嵌入式并发应用中,很多时候采用多线程架构,嵌入式Linux也支持pthread库,Linux上的线程,1、函数原型2、参数说明 (1)thread用于返回线程标识符 (2)attr 用于传入线程属性 (3)start_

19、routine是线程开始执行时调用的函数名 (4)arg为传递给start_routine的参数,线程创建,3、使用说明:(1)创建线程实际上就是确定该线程启动时调用的入口函数(2)pthread_create过后,会自动使线程成为可执行(3)pthread_create返回后,线程自动进入就绪态,start_routine将被CPU调度执行.4、线程中,通过phread_self可以获得自身线程ID,线程创建,线程创建示例,1、主进程结束之后,进程上的所有线程也结束2、线程入口函数执行完毕,线程自动结束3、在线程中不能调用exit函数退出,exit会退出整个主进程4、线程的退出函数是phre

20、ad_exit,只会退出线程自身线程退出后,需要回收退出状态占用的资源!,线程退出,当线程为非死循环执行的任务时,先分离自己,实现资源自动回收,线程回收示例,1、在多个线程间共享的资源,访问时必须加以保护,确保同一时间只有一个线程访问数据2、可以通过pthread_mutex(互斥锁)实现互斥保护:(1)在访问共享资源前对互斥锁加锁,在访问完成后互斥锁解锁 (2)对互斥锁加锁以后,任何其他试图再次加锁的线程将被阻塞直到当前线程解锁 (3)多个等待同一互斥锁的线程会阻塞在互斥锁等待队列,拥有锁资源的线程解锁后,只有一个线程编程进入就绪状态,其他线程继续阻塞,等待下一次解锁,多线程互斥访问,1、初

21、始化一个互斥锁 pthread_mutex_init() /更为简便的初始化方法 static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER;2、互斥锁加锁 pthread_mutex_lock()3、互斥锁解锁 pthread_mutex_unlock(),互斥锁使用,互斥锁示例,课程安排,Linux系统文件与I/O Linux系统多进程并发 Linux系统多线程并发 Linux系统网络通信,TCP/IP协议,TCP/IP网络协议栈分为应用层(Application)、传输层(Transport)、网络层(Network)和链路层(L

22、ink)四层,Linux 对TCP/IP的实现,Linux 对TCP/IP的实现,Linux以分层的软件结构实现了TCP/IP协议 用网络驱动程序实现数据链路层功能 内核内置的TCP/IP协议栈处理IP,TCP/UDP以IP转发功能 用户程序通过套接字(SOCKET)与协议栈打交道SOCKET是一个通用的接口,一般应用开发者只需掌握基于因特网IPV4的Socket TCP和UDP网络通讯开发即可,TCP与UDP,TCP与UDP属于端对端的传输层协议 TCP是面向连接的: 需要在数据传送之前在设备之间建立“逻辑连接”,数据传输结束,“逻辑连接”即被断开。 “逻辑连接”保证了数据传输的可靠性,所以面向连接协议是可靠的UDP是面向无连接的 不需要建立“逻辑连接”,在源端在需要的时候就可以立即开始发送数据。 无连接协议是不可靠的,但通讯效率更高,UDP协议格式,TCP协议格式,UDP编程流程,UDP客户端示例,UDP服务器示例,UDP编程流程,UDP通信过程,TCP编程流程,TCP客户端示例,TCP服务器示例,TCP编程流程,TCP 通信过程,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报