一.上集回顾
建议先学上篇博客,再向下学习,上篇博客的链接如下:
二.线程互斥


1.快速见一见,没有加保护,会有什么问题
#include <iostream>
#include "Thread.hpp"
#include <vector>
using namespace ThreadModule;
#define NUM 4
int ticketnum = 10000;//临界资源
void Ticket()
{
while(true)
{
if(ticketnum > 0)
{
usleep(1000);
//1.抢票
printf("get a new ticket, id: %d\n",ticketnum--);
}
else
{
break;
}
}
}
int main()
{
//1.构建线程对象
std::vector<Thread> threads;
for(int i = 0;i < NUM;i++)
{
threads.emplace_back(Ticket);
}
//2.启动线程
for(auto& thread:threads)
{
thread.Start();
}
//3.等待线程
for(auto& thread:threads)
{
thread.Join();
}
return 0;
}


代码为啥会出现这个问题呢?
![]()


ticketnum--这一条指令,就会被转换成为三条汇编



所以,这个ticketnum--不是原子性的(ticketnum > 0 也不是原子的)






![]()
![]()
要么是一行汇编,要么是多行代码,但是加锁保护
2.解决方案

所有对资源的保护,都是对临界区代码的保护,因为资源是通过代码访问的!

3.接口介绍
a.锁的初始化


最低0.47元/天 解锁文章
1067

被折叠的 条评论
为什么被折叠?



