嵌入式操作系统开发
学习内容:
1.线程的主动退出
pthread_exit
#include <pthread.h>
void pthread_exit(void *retval);
功能
线程调用这个函数时,可以主动退出(终止)
它和exit()很像,exit()是终止整个程序,而pthread_exit是终止次线程
如果你在次线程里面调用错误,调用的是exit,整个线程就终止了
返回值
成功返回0,失败返回非零值
参数
retval:线程结束的返回值
如果返回值很多时,就会封装成一个结构体,返回结构体变量的地址即可
return函数
#include <pthread.h>
void pthread_cleanup_push(void (*routine)(void *),void *arg);
void pthread_cleanup_pop(int execute);
弹栈线程退出处理函数的几种条件
pthread_cleanup_push(!0):主动弹栈
另:pthread_cleanup_push(0):就是不弹栈
如果线程是被别人调用pthread_cancel取消的,也会弹栈
如果调用pthread——exit函数也是会主动弹栈
注意:return退出的话是不会自动弹栈的,想要自动弹栈用pthread——cleanup——pop(!0)
一、线程等待的目的:
(1)保证线程的退出顺序:保证一个线程退出并且回收资源后,允许下一个进程退出。
(2)回收线程退出时的资源情况:保证当前线程退出后,创建新线不会复用刚才退出线程的地址空间。
(3)获得新线程退出时的结果是否正确退出返回值。
二、线程的状态:
1、可结合态(默认状态):这种状态下的线程是可能被其他进程回收资源或被杀死的。
2、可分离态:这种状态下的线程不能被其他进程回收资源或被杀死,它存储的资源在它终止时由系统自动回收。
3、线程状态的转换:
线程分离函数:
#include <pthread.h>
int pthread_detach(pthread_t thread);
//功能:如果此线程不希望别人调用pthread_join函数来回收,而是希望自己在运行结束时,自动回收资源调用pthread_detach
(将pthread_detach()中的线程变为分离态)
//返回值:成功返回0;错误则返回错误结果
//参数:thread:要分离的那个此线程的TID
tach_struct存储双方的进程信息
信息:
- 调度优先级
- 所有的进程id
- 地址空间
线程切换的开销低,因为实质上是函数的切换。
进程与线程的区别——进程是线程的boss
根本区别—进程管资源、线程管执行:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位。
进程是资源分配最小单位;线程是程序执行的最小单位。
内存与开销—每个进程拥有独立的地址空间,多个线程共享进程的地址空间,进程之间的切换比线程开销大、线程可频繁切换。
进程的调度必须依靠频繁的加锁来保持线程的同步,影响线程的并发性能
进程比线程更健康,多进程互相独立,一个进程崩溃对其他进程无影响,而一个线程的崩溃可能影响其他线程和程序
线程之间的通信方便(小数据量的),同一进程下,线程共享全局变量还有静态变量等数据,而进程之间的通信需要以通信的方式进行(IPC),不过如何处理好同步与互斥,是编写多线程程序的难点
多线程的代码结构比多进程的代码结构简单易读
资源开销—线程可以看做轻量级的进程
环境运行—线程是进程的一部分、进程可有多个线程
如何处理好同步与互斥,是编写多线程的难点
线程信号量:
线程信号量使用步骤:
1.定义信号量集合
sem t sem【3】
线程信号量集合其实就是一个数组,数组每个元素就是一个信号量
sem【0】:第一个信号量
sem【1】:第二个信号量
sem【2】:第三个信号量
2.初始化集合中的每个信号量
#include <semaphore.h>
int sem_init(sem_t*sem,int pthread,unsiged int value)
功能:
初始化线程信号量集合中的某个信号量,给它设置一个初值
返回值:
成功返回0,失败返回-1,errno被设置
信号量的错误号不是返回的,而是直接设置到errno
3.p,v操作
4.进程结束时,删除线程信号量集合