热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux:多线程互斥锁

1.互斥锁作用在Linux下,多个线程拥有同一个虚拟地址空间,若多个线程对同一块数据进行操作,可能会产生二义性。造成逻辑混乱。为了保证不发生这些,就需要线程安全。线程安全的概念:多
1.互斥锁作用

在Linux下,多个线程拥有同一个虚拟地址空间,若多个线程对同一块数据进行操作,可能会产生二义性。造成逻辑混乱。为了保证不发生这些,就需要线程安全。

线程安全的概念:多个线程对同一个临界资源进行争抢访问,但不会造成数据二义性。
线程安全的实现:就要保证同步与互斥。

同步的实现:条件变量/信号量
互斥的实现:互斥锁/信号量

互斥锁为资源引入一个状态信息:锁定/非锁定
当线程要访问一个临界资源的时候,需要先查看这个锁的状态信息

1.若处于开锁(非锁定)状态,就申请到了对临界资源的访问权,并立即更改锁的状态置为锁定状态。
2.若处于锁定状态,则当前线程阻塞,有R(运行)状态变成S(休眠)状态。
2.互斥锁操作

1.定义互斥锁变量
pthread_mutex_t 是一个结构体,锁的类型就是这个。

2.初始化互斥锁
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
第一个参数传递定义的互斥锁的指针,第二个参数是设置互斥锁的属性
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
这种在定义的时候初始化的方式也可以,POSIX定义了一个宏PTHREAD_MUTEX_INITIALIZER来初始化锁。

3.上锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
阻塞接口
int pthread_mutex_trylock(pthread_mutex_t *mutex);
非阻塞接口

4.解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);

5.销毁锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);

3.互斥锁原理

在pthread_mutex_t结构体中,有一个变量,当它不为0的时候,线程可以继续执行,否则线程被阻塞。当解锁的时候,会进行唤醒操作,唤醒因为没有获取锁而阻塞的线程。
点这里,这个博客里具体讲了加锁解锁的原理
对锁的状态判断和修改锁的值是一个原子操作,否则可能会导致,一个线程刚判断完可以访问资源进行加锁,另一个线程也正在判断。那这样两个线程可能都会对资源进行访问。
这个原子操作的原理是

1.首先在寄存器里面设置一个变量0。

2.在对锁访问的时候会有一个原子操作,将内存中锁中的值和寄存器中的这个0进行交换。

3.再去判断寄存器中的值,如果是1则可以获取锁,如果是0,就无法获得锁。

《Linux:多线程-互斥锁》

4.互斥锁实例–大妈抢鸡蛋

//通过大妈抢鸡蛋的例子,体会线程安全的重要性以及认识了解互斥锁
//每个线程代表一个大妈。
#include
#include
#include
#include
#define MAX_THR 4 //设置创建线程数量
pthread_mutex_t _mutex;//创建互斥锁变量
int egg = 100;//设置100个鸡蛋
void *Dama(void *arg)
{
while(1)
{
pthread_mutex_lock(&_mutex);//先上锁,让其他线程阻塞
if(egg > 0)
{
printf("%p抢到了第%d个鸡蛋\n",pthread_self(),egg--);
//大妈每次抢一个鸡蛋
}
else
{
printf("鸡蛋抢完了\n");
pthread_mutex_unlock(&_mutex);//解锁后退出线程
pthread_exit(NULL);
}
pthread_mutex_unlock(&_mutex);//抢到了进行解锁
usleep(100);
}
return NULL;
}
int main()
{
int i;
pthread_t tid[MAX_THR];//线程ID
pthread_mutex_init(&_mutex,NULL);//互斥锁初始化
for(i = 0;i < MAX_THR; i++)
{
int ret = pthread_create(&tid[i],NULL,Dama,NULL);//创建线程
//参数解释:
//1.保存当前线程ID
//2.设置线程属性
//3.设置线程要去执行的函数地址
//4.需要给线程函数中传递的参数
if(ret!=0)//判断线程是否为创建失败
{
perror("pthread error\n");
return -1;
}
}
for(i = 0;i < MAX_THR; i++)
{
pthread_join(tid[i],NULL);//线程等待
}
pthread_mutex_destroy(&_mutex);//销毁互斥锁
return 0;
}

推荐阅读
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • C语言编程gcc怎么生成静态库.a和动态库.so
    这篇文章将为大家详细讲解有关C语言编程gcc怎么生成静态库.a和动态库.so,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • Linux 中使用 clone 函数来创建线程
    2019独角兽企业重金招聘Python工程师标准Linux上创建线程一般使用的是pthread库实际上libc也给我们提供了创建线程的函数那就是cloneintclone(i ... [详细]
  • 不知道你是否还记得之前在进程中的信号处理时,提到过阻塞信号集与未决信号集的概念,如果你已经忘记了,请参考《阻塞信号与未决信号》一文回忆一下 ... [详细]
  • 主要用的线程函数:1.创建线程:12intpthread_create(pthread_t*thread,constpthread_attr_ ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 作者一直强调的一个概念叫做oneloopperthread,撇开多线程不谈,本篇博文将学习,怎么将传统的IO复用pollepoll封装到C++类中。1.IO复用复习使用p ... [详细]
author-avatar
高小原gy_941
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有