《第5章 嵌入式Linux多线程编程.ppt》由会员分享,可在线阅读,更多相关《第5章 嵌入式Linux多线程编程.ppt(27页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、嵌入式应用程序设计嵌入式应用程序设计第5章 嵌入式Linux多任务编程 第1章 搭建嵌入式Linux开发环境第2章 嵌入式文件I/O编程第3章 嵌入式Linux多任务编程第4章 嵌入式Linux进程间通行第第5章章 嵌入式嵌入式Linux多线程编程多线程编程第6章 嵌入式Linux网络编程第7章 Qt图形编程第8章 嵌入式Linux设备驱动编程第9章 Qt聊天项目设计课程安排课程安排:2 5.1 线程基本编程5.2 线程之间的同步与互斥5.3 线程属性5.4 多线程实验5.5 小结5.6 思考与练习本章课程:本章课程:3 1.1.1 嵌入式系统简介计算机、通信、消费电子的一体化趋势嵌入式系统定
2、义:嵌入式系统是指以应用为中心,以计算机技术为基础,软件硬件可剪裁,适应应用系统,对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。硬件+软件硬件:由嵌入式微处理器、外围硬件设备组成软件:括底层系统软件和用户应用软件嵌入式系统应用领域:5.1 线程基本编程4 创建线程实际上就是确定调用该线程函数的入口点,这里通常使用的函数是pthread_create()。在线程创建之后,就开始运行相关的线程函数,在该函数运行完之后,该线程也就退出了,这也是线程退出的一种方法。另一种退出线程的方法是使用函数pthread_exit(),这是线程的主动行为。pthread_join()可以用于将当前线程
3、挂起来等待线程的结束。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源就被收回。pthread_cancel()向其他线程发送终止信号,但在被取消的线程的内部需要调用pthread_setcancel()函数和pthread_setcanceltype()函数设置自己的取消状态。5.1 线程基本编程5 phtread_create()函数语法:phtread_exit()函数语法:5.1 线程基本编程6 phtread_join()函数语法:phtread_cancel()函数语法:5.1 线程基本编程7 5.2.1 互斥锁线程控制互斥
4、锁是用一种简单的加锁方法来控制对共享资源的原子操作。互斥锁只有两种状态,也就是上锁和解锁,可以把互斥锁看作某种意义上的全局变量。在同一时刻只能有一个线程掌握某个互斥锁,拥有上锁状态的线程能够对共享资源进行操作。若其他线程希望上锁一个已经被上锁的互斥锁,则该线程就会挂起,直到上锁的线程释放掉互斥锁为止。互斥锁可以分为快速互斥锁、递归互斥锁和检错互斥锁。这三种锁的区别主要在于其他未占有互斥锁的线程在希望得到互斥锁时是否需要阻塞等待。快速锁是指调用线程会阻塞直至拥有互斥锁的线程解锁为止。递归互斥锁能够成功地返回,并且增加调用线程在互斥上加锁的次数,而检错互斥锁则为快速互斥锁的非阻塞版本,它会立即返回
5、并返回一个错误信息。默认属性为快速互斥锁。5.2 线程之间的同步和互斥8 5.2.1 互斥锁线程控制互斥锁的基本操作:互斥锁初始化:pthread_mutex_init()互斥锁上锁:pthread_mutex_lock()互斥锁判断上锁:pthread_mutex_trylock()互斥锁接锁:pthread_mutex_unlock()消除互斥锁:pthread_mutex_destroy()5.2 线程之间的同步和互斥9 5.2.1 互斥锁线程控制pthread_mutex_init()函数语法:5.2 线程之间的同步和互斥10 5.2.1 互斥锁线程控制pthread_mutex_lo
6、ck()函数语法:5.2 线程之间的同步和互斥11 5.2.2 信号量线程控制信号量也就是操作系统中所用到的PV原子操作,它广泛用于进程或线程间的同步与互斥。信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。PV原子操作是对整数计数器信号量sem的操作。一次P操作使sem减一,而一次V操作使sem加一。进程(或线程)根据信号量的值来判断是否对公共资源具有访问权限。当信号量sem的值大于等于零时,该进程(或线程)具有公共资源的访问权限;相反,当信号量sem的值小于零时,该进程(或线程)就将阻塞直到信号量sem的值大于等于0为止。5.2 线程之间的同步和互斥12 5.2.2 信号量
7、线程控制PV原子操作主要用于进程或线程间的同步和互斥这两种典型情况。5.2 线程之间的同步和互斥互斥同步13 5.2.2 信号量线程控制Linux实现了POSIX的无名信号量,主要用于线程间的互斥与同步。这里主要介绍几个常见函数。sem_init()用于创建一个信号量,并初始化它的值。sem_wait()和sem_trywait()都相当于P操作,在信号量大于零时它们都能将信号量的值减一,两者的区别在于若信号量小于零时,sem_wait()将会阻塞进程,而sem_trywait()则会立即返回。sem_post()相当于V操作,它将信号量的值加一同时发出信号来唤醒等待的进程。sem_getva
8、lue()用于得到信号量的值。sem_destroy()用于删除信号量。5.2 线程之间的同步和互斥14 5.2.2 信号量线程控制sem_init()函数语法:5.2 线程之间的同步和互斥15 5.2.2 信号量线程控制sem_wait()函数语法:5.2 线程之间的同步和互斥16 pthread_create()函数的第二个参数(pthread_attr_t*attr)表示线程的属性。如果该值设为NULL,就是采用默认属性,线程的多项属性都是可以更改的。这些属性主要包括绑定属性、分离属性、堆栈地址、堆栈大小以及优先级。其中系统默认的属性为非绑定、非分离、缺省1M的堆栈以及与父进程同样级别的
9、优先级。5.3 线程属性17 绑定属性绑定属性就是指一个用户线程固定地分配给一个内核线程,因为CPU时间片的调度是面向内核线程(也就是轻量级进程)的,因此具有绑定属性的线程可以保证在需要的时候总有一个内核线程与之对应。而与之对应的非绑定属性就是指用户线程和内核线程的关系不是始终固定的,而是由系统来控制分配的。分离属性 分离属性是用来决定一个线程以什么样的方式来终止自己。5.3 线程属性18 pthread_attr_init()pthread_attr_init()函数对属性进行初始化pthread_attr_init()函数语法:5.3 线程属性19 pthread_attr_setscop
10、e()pthread_attr_setscope()函数设置线程绑定属性pthread_attr_setscope()函数语法:5.3 线程属性20 pthread_attr_setdetachstate()pthread_attr_setdetachstate()函数设置线程分离属性pthread_attr_setdetachstate()函数语法:5.3 线程属性21 pthread_attr_getschedparam()pthread_attr_getschedparam()函数获得线程优先级pthread_attr_getschedparam()函数语法:5.3 线程属性22 pth
11、read_attr_setschedparam()pthread_attr_setschedparam()函数设置线程优先级pthread_attr_setschedparam()函数语法:5.3 线程属性23 实验目的通过编写经典的“生产者消费者”问题的实验,读者可以进一步熟悉Linux中的多线程编程,并且掌握用信号量处理线程间的同步和互斥问题。实验内容“生产者消费者”问题描述如下。有一个有限缓冲区(这里用有名管道实现FIFO式缓冲区)和两个线程:生产者和消费者。他们分别不停地把产品放入缓冲区和从缓冲区中拿走产品。一个生产者在缓冲区满的时候必须等待,一个消费者在缓冲区空的时候也必须等待。另外,因为缓冲区是临界资源,所以生产者和消费者之间必须互斥执行。它们之间的关系如下图这里要求使用有名管道来模拟有限缓冲区,并且使用信号量来解决“生产者消费者”问题中的同步和互斥问题 5.4 多线程实验24 1.多线程编程框架2.线程的控制操作3.线程属性的概念1.5 小结25 1.通过查找资料,查看主流的嵌入式操作系统是如何处理多线程操作的。2.将一个多进程程序改写成多线程程序,对两者加以比较,有何结论?3.使用线程实现串口通信。1.6 思考与练习2627
限制150内