#include <stdio.h>#include <pthread.h>#include <unistd.h>pthread_mutex_t mutex;// 创建锁变量//全局变量,所有线程共享int ticket = 10;void* get_tickets(void* arg){ long id = (long)arg; while (1){usleep(1000);// 加锁pthread_mutex_lock(&mutex);if (ticket > 0){// 有票--ticket;printf("线程%ld获得一张票,剩余%d张票\n",id,ticket);// 解锁pthread_mutex_unlock(&mutex);}else{// 无票 , 退出// 解锁pthread_mutex_unlock(&mutex);break;} }}int main(){ pthread_t t[5]; // 初始化锁 pthread_mutex_init(&mutex, NULL); // 创建5个线程 long i = 0; for (; i < 5; ++i) { pthread_create(t+i, NULL, get_tickets, (void*)(i+1)); } // 释放5个线程 for (i = 0; i < 5; ++i) {pthread_join(t[i], NULL); } // 销毁锁 pthread_mutex_destroy(&mutex); return 0;}运行结果如下:
文章插图
总结几点并回答几个问题:
锁的作用: 对临界区进行保护,所有的执行流线程都必须遵守这个规则:lock——>访问临界区——>unlock
需要注意的点:
- 所有的线程必须看到同一把锁,锁本身就是临界资源,所以锁本身需要先保证自身安全申请锁的过程不能出现中间态,必须保证原子性
- 任一线程持有锁之后 , 其它线程如果还想申请锁时申请不到的,保证互斥性
进入等待队列进行等待 , 从运行队列转移到等待队列,状态由R变成S,持有锁的线程unlock之后,需要唤醒等待队列中的第一个线程
struct mutex{ int lock;// 0 1 // ... sturct wait_queue;//锁下的等待队列}互斥量的原理大多数体系结构都提供了swap或exchange指令 , 该指令的作用是把寄存器和内存单元的数据相交换,由于只有一条指令,保证了原子性,即使是多处理器平台,访问内存的总线周期也有先后,一个处理器上的交换指令执行时另一个处理器的交换指令只能等待总线周期 。下面是lock和unlock的伪代码
lock: movb $0, %a1 # 把0值放进寄存器a1里 xchgb %a1, mutex # 交换a1寄存器的内容和锁的值(无线程使用锁时 , metux的值为1) if (%a1 > 0)return 0; # 得到锁 else挂起等待; goto lock;unlock: movb $1 mutex #把1赋给锁 唤醒等待的线程; return 0;在上述加锁的伪代码中演示了上步骤:
- 对寄存器的内容进行清0
- 把mutex的值(被使用值为0,未被使用值为1)和寄存器的内容进行交换
- 寄存器的内容为1代表得到了锁,为0代表未得到锁,要挂起等待
文章插图
解锁的伪代码步骤(只有有锁的线程才可以执行到这段代码):
- 把mutex的值改为1
- 唤醒等待锁的线程
举个例子:
文章插图
这里线程1先申请资源1,申请到了之后,资源1被锁死(资源1会永远被线程1申请,因为只有申请到资源2执行完临界代码,才会释放掉资源1,此时线程1被卡在申请资源2的点,根本走不到释放资源1的代码,所以会一直被线程1占有) , 线程2无法申请,线程2先申请资源2,同样资源2也被锁死,这样当线程1继续向下申请资源2的时候,就被阻塞在那里,线程2在向下申请资源1的时候,也被阻塞在那里,这就形成了死锁,永远解不了锁 。
死锁引起的原因:
- 竞争不可抢占资源引起死锁:这就是上述情况,都在等待对方占有的不可抢占的资源
- 竞争可消耗资源引起的死锁:有p1,p2,p3三个进程,p1向p2发送消息并接受p3发送的消息,p2向p3发送消息并接收p1的消息,p3向p1发送消息并接收p2的消息,如果设置时先接收消息后发送消息,则所有的信息都不能发送,这就造成死锁
推荐阅读
- 华为watch3可以使用微信吗_华为watch3有微信吗
- Python 多重继承时metaclass conflict问题解决与原理探究
- 神仙记事录第十二章怎么过
- 嘉峪关到张掖-嘉峪关到张掖多少公里
- 多玩LOL盒子战绩查询 英雄联盟战绩查询在线查询系统
- dnf公会勋章怎么获得(dnf公会传说勋章多久能获得)
- 【多服务场景化解决方案】AR虚拟技术助力智能家装
- 一 Linux--多线程
- pta第二次博客
- 1斤等于多少磅 一斤等于多少磅