C多线程开发补充

死锁

死锁:是指多个线程因竞争资源而造成的一种互相等待的僵局。例如A等待B释放线程然后去CPU时间片,但B也在等待A在释放线程,这种情况就会造成死锁的情况。

死锁产生的原因主要是:系统资源竞争,进程运行推进顺序不合适。

死锁产生的四个必要条件:

互斥条件:一个资源一次只能被一个进程使用。

请求与保持条件: 进程已经保持了至少一个资源,又提出了新的资源请求,而该资源已经被其他进程占有。此时请求进程被阻塞,而对自己已获得的资源保持不放。

不可剥夺条件:进程所获得的资源在未使用完之前,不能被其他进程强行夺走,即只能由进程自己主动释放。

循环等待条件:若干进程间形成首尾相接循环等待资源的关系。

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而”只要上述条件之一不满足,就不会发生死锁“。
线程同步机制:互斥锁+条件变量+读写锁

  1. 互斥锁:适用于线程可用的资源只有一个,需要互斥访问的情况
  2. 条件变量:适用线程之间构成条件等待关系的情况
  3. 读写锁:提高互斥锁在数据库系统数据访问(大量读,较少写)等应用领域的效

互斥锁简单来说是以排他方式防止共享数据被并发访问。且它只有两种状态0(允许)和1(禁止)。可将其看成是特殊意义的全局变量。

使用互斥锁的方式是1.首先申请互斥锁,若互斥锁处于锁定状态,则线程被阻塞。若是处于解锁状态,则申请到该锁并立即占有该锁,使锁处于锁定状态,其他线程访问该资源时会被排他。2.是被锁定的线程才能释放该互斥锁,其他线程试图释放操作是无效的。 

1.pthread_mutex_t lock;定义该互斥锁(全局变量)
2.初始化互斥锁	 pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
mutex      要初始化的互斥锁的指针
mutexattr  要初始化的互斥锁的属性;NULL表示使用默认属性
成功返回0 否则返回一个错误编号

阻塞申请互斥锁	pthread_mutex_lock  (pthread_mutex_t *mutex);

非阻塞申请互斥锁	pthread_mutex_trylock (pthread_mutex_t *mutex);

线程任务完成后释放互斥锁	pthread_mutex_unlock (pthread_mutex_t *mutex);

不使用后需要销毁互斥锁	pthread_mutex_destroy (pthread_mutex_t *mutex);

静态分配的互斥锁:置为常量PTHREAD_MUTEX_INITIALIZER,属性为NULL,也可以调用pthread_mutex_init函数

动态分配的互斥锁:例如通过调用malloc函数分配的互斥锁,只能调用pthread_mutex_init,且在释放内存前需要调用pthread_mutex_destroy

条件变量

条件变量与互斥锁不同,它是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。条件变量不能单独使用,必须配合互斥锁一起实现对资源的互斥访问

条件变量分为两部分:条件和变量。条件本身是由互斥量保护的,线程在改变条件状态前先要锁住互斥量。
条件变量使线程睡眠等待某种条件出现。条件变量主要包括两个动作:一个线程等待”条件变量的条件成立”而挂起;另一个线程使”条件成立”(给出条件成立信号)。

条件的检测是在互斥锁的保护下进行的。如果一个条件为假,一个线程自动阻塞,并释放等待状态改变的互斥锁。如果另一个线程改变了条件,它发信号给关联的条件变量,唤醒一个或多个等待它的线程,重新获得互斥锁,重新评价条件。如果两进程共享可读写的内存,条件变量可以被用来实现这两进程间的线程同步。
 

pthread_cond_t condition;定义全局变量
1.初始化条件变量	pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t *restrict cond_attr);
cond      指向要初始化的条件变量指针
cond_attr 指向属性对象的指针,该属性对象定义要初始化的条件变量的特性;NULL表示使用默认属性;

阻塞等待条件变量	pthread_cond_wait  (pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
cond   指向要等待的条件变量的指针
mutex  指向与条件变量cond关联的互斥锁的指针

在指定的时间内阻塞等待条件变量	pthread_cond_timedwait (pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
nd    指向要等待的条件变量的指针
    mutex   指向与条件变量cond关联的互斥锁的指针
    abstime 等待过期时的绝对时间,如果在此时间范围内取到该条件变量函数将返回
            使用UTC时钟,即为一个绝对时间,该数据结构声明如下
            struct timespec
            {
                long ts_sec;   //秒部分
                long ts_nsec;  //纳秒部分
            }
            使用这个结构时,需要指定愿意等待多长时间,时间值是一个绝对数而不是相对数。
            例如,如果能等待3分钟,就需要把当前时间加上3分钟再转换到timespec结构,而不是把3分钟转换成timespec结构。

通知等待该条件变量的第一个线程	pthread_cond_signal  (pthread_cond_t *cond);
如果cond没有阻塞任何线程,则此函数不起作用
如果cond阻塞了多个线程,则调度策略将确定要取消阻塞的线程
显然在此函数被调用时隐含了释放当前线程占用的信号量的操作

通知等待该条件变量的所有线程	pthread_cond_broadcast;(pthread_cond_t *cond);
如果cond上没有阻塞任何线程,则此函数不起作用

销毁条件变量状态	pthread_cond_destroy(pthread_cond_t *cond);
while(1);
意义:这是一个死循环,代码不再向下执行。
用途:
1. 一般在调试代码时,为了检测一部分代码是否OK,防止后面的代码干扰执行结果,会在观测点加上while(1);
2.有些代码检测到运行错误时,会抛出错误(打印、设置错误码),然后进入while(1);
3.机器需要复位时,停止喂看门狗,进入while(1); 迫使看门狗超时,产生硬件复位

while( 1 ) { 代码 }
意义:这里将会重复执行{}中的代码
用途:
1.单片机在不使用操作系统时,主程序一般都使用这种架构
2.操作系统中的进程,执行任务时,有些也会使用这种架构
3.{}中的代码不停地检测某个条件,当条件符合时,跳出该循环,继续向下执行
4.停留在此,等待中断

应用案例

 

借鉴并整理:

(35条消息) C语言多线程编程-死锁和线程同步方式介绍(一)_shuaixio的博客-CSDN博客_c线程同步

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值