线程的创建和退出

线程的概念

使用多线程带来的一些好处

  • 同步变成模式 VS 异步编程模式

  • 多个进程必须使用操作系统提供的复杂机制才能实现内存和文件描述符的共享 VS 多个线程可以自动的访问相同的存储地址空间和文件描述符

  • 单线程处理多任务 VS 多线程处理多任务

  • 改善响应时间,输入输出等需要阻塞的部分可以和其它部分分开

一些基础认知

每个线程包含了执行环境所必需的信息,包括:

  • 线程ID
  • 一组寄存器值
  • 调度优先级和策略
  • 信号屏蔽字
  • errno变量
  • 线程私有数据

一个进程的所有信息对该进程的线程都是共享的,包括:

  • 代码段
  • 全局内存和堆内存
  • 文件描述符

创建线程

int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, void *(*start_rtn)(void *), void *arg)
  • tidp,指向线程id的内存单元
  • attr,用于定制各种不同的线程属性,如调度优先级和策略,栈空间等
  • start_rtn,线程入口函数
  • arg,无类型指针参数,如果有多个参数,需要放到一个结构体中

线程ID会发回给tidp,但是在线程内部使用线程ID建议使用pthread_self()函数,因为存在一种情况,当线程开始运行的时候,tidp还没有被赋值。

线程终止

线程中的任意线程调用了exit,整个线程就会被终止
线程的退出方式有3中:
- 线程可以简单的在线程中返回
- 线程可以被同一进程中的其它线程取消pthread_cancel
- 线程可以调用pthread_exit

void pthread_exit(void *rval_ptr)
void pthread_join(pthread_t thread, void **rval_ptr)

调用线程将一直阻塞,直到上述三种终止线程的情况之一发生,如果简单的在线程中返回,rval_ptr包含返回码,如果线程取消,则rval_ptr指向的单元被设置为PTHREAD_CANCELED

要注意的是pthread_exit返回的参数如果是局部栈空间,那么用pthread_join捕获的参数是不确定的

pthread_cancel(pthread_t tid)

注意 pthread_cancel并不断等待线程终止,它只是提出请求

线程同步

当一个线程可以修改的变量,其它线程也可以读取或者修改的时候,我们就需要对这些线程进行同步,确保它们在访问变量的存储内容时不会访问到无效的值。

如果一个写操作需要两个周期,另外一个线程的读取操作刚好在这两个周期中间,读出的值就是一个无效值

互斥量

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
int pthread_mutex_destroy(pthread_mutex_t *mutex)

注意 也可以在定义互斥量的时候静态分配互斥量PTHREAD_MUTEX_INITIALIZER,这种情况下就不需要调用pthread_mutex_destroy

int pthread_mutex_lock(pthread_mutex_t *mutex)
int pthread_mutex_trylock(pthread_mutex_t *mutex)
int pthread_mutex_unlock(pthread_mutex_t *mutex)

如果获取不到锁,则pthread_mutex_lock会一直阻塞等待锁,采用非阻塞的方式是pthread_mutex_trylock,如果锁住互斥量,则不阻塞直接返回0,如果互斥量处于锁住状态,那么pthread_mutex_trylock就会失败,不能锁住互斥量,返回EBUSY。

pthread_mutex_trylock的使用场景,当你已经启动了一个任务并且正在进行中,这时候外部环境不知道你是否完成,又来了一次任务请求,这时候我们最后用trylock的方式,及时告诉外部环境一个返回值,而不是阻塞在那让外部环境以为命令执行成功了。
在我们的项目中,比如OTA任务,更改本地设备参数的任务,都需要用到trylock来防止下一次命令到来时引入的同步问题。

避免死锁

可能出现的死锁只会发生在一个线程试图锁住另一个线程以相反顺序锁住的互斥量
解决死锁的办法有两种

一种思路是仔细控制互斥量加锁的顺序来避免死锁
一种思路是先释放占有的锁,然后过一段时间再试,这种情况下使用pthread_mutex_trylock接口避免死锁,如果已经占有某些锁,且trylock返回成功,那么可以前进,但是如果trylock不能获取锁,可以先释放已经占用的锁,做好清理工作,过一段时间后再试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值