当前位置: 首页 > article >正文

15-4-线程-线程同步之互斥量加锁解锁

一、概念

互斥量:互斥量(mutex)从本质上来说是一把锁,在访问共享资源前对加互斥量(实现加锁),在访问完成后释放互斥量(实现解锁)。

加锁后,任何其他试图再次加锁的线程将会被阻塞直到当前线程释放该互斥锁。

如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为可运行状态的线程可以加锁,其他线程将会看到互斥锁依然被锁住,只能回去等待它重新变为可用。在这种方式下,每次只有一个线程可以向前运行。

  在设计时需要规定所有的线程必须遵守相同的数据访问规则。只有这样,互斥机制才能正常工作。操作系统并不会做数据访问的串行化。如果允许其中的某个线程在没有得到锁的情况下也可以访问共享资源,那么即使其它的线程在使用共享资源前都获取了锁,也还是会出现数据不一致的问题。

互斥变量用pthread_mutex_t数据类型表示。在使用互斥变量前必须对它进行初始化,可以把它置为常量PTHREAD_MUTEX_INITIALIZER(只对静态分配的互斥量),也可以通过调用pthread_mutex_init函数进行初始化。如果动态地分配互斥量(例如通过调用malloc函数),那么在释放内存前需要调用pthread_mutex_destroy。

二、.API

 之前学习的“信号量”里也有类似加锁,解锁的功能(放回钥匙,和取钥匙);

接下来将学习线程中的加锁和解锁。

创建及销毁互斥锁

#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
int pthread_mutex_destroy(pthread_mutex_t mutex);

 返回:若成功返回0,否则返回错误编号
要用默认的属性初始化互斥量,只需把attr设置为NULL。

三、实验

功能:

创建2个线程t1,t2;

锁初始化。

运行线程1,在该线程中加锁-->屏幕输出(业务逻辑)--->解锁(在这期间线程二试图加锁,是会被阻塞的,直到线程一解锁后,线程二才可以以加锁)。

接着运行线程2,在该线程中加锁-->屏幕输出(业务逻辑)--->解锁。

(线程1,2的运行不分先后,但一定是先在线程1里加锁,导致线程2的业务逻辑被阻塞)

销毁锁。

代码::

#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mutex;
void *fun1(void *arg)
{
        pthread_mutex_lock(&mutex);

        printf("t1:%ld thread is created\n",(unsigned long)pthread_self());
        printf("param = %d\n",*((int *)arg));

        pthread_mutex_unlock(&mutex);
}
void *fun2(void *arg)
{
        pthread_mutex_lock(&mutex);

        printf("t2:%ld thread is created\n",(unsigned long)pthread_self());
        printf("param = %d\n",*((int *)arg));

        pthread_mutex_unlock(&mutex);
}
int main()
{
        int ret;
        int param = 100;
        pthread_t t1;
        pthread_t t2;
        pthread_mutex_init(&mutex,NULL);
        ret = pthread_create(&t1,NULL,fun1,(void *)&param);
        if(ret = 0)
        {
                printf("creat t1 success\n");
        }

        ret = pthread_create(&t2,NULL,fun2,(void *)&param);
        if(ret = 0)
        {
                printf("creat t2 success\n");
        }
        pthread_join(t1,NULL);
        pthread_join(t2,NULL);
        pthread_mutex_destroy(&mutex);
        return 0;
}

 四、注意点

使用互斥锁的一些注意点:

1.创建和销毁是相呼应的,所以在程序中创建锁后也要及时销毁锁(pthread_mutex_init()+pthread_mutex_destroy())
加锁和解锁是相呼应的。

2.通过互斥锁限制共享资源的访问


http://www.kler.cn/news/16275.html

相关文章:

  • matlab绘制折线图基本操作
  • 『python爬虫』04. 爬虫需要知道的HTTP协议知识(保姆级图文)
  • 云和恩墨荣获2023数字中国创新大赛·信创赛道“最具发展潜力奖”等4个奖项
  • C语言从入门到精通第16天(指针的定义与基本使用)
  • PID控制---基于python模拟
  • 面向画布(Canvas)的JavaScript库
  • 【c语言小项目】基于easyX的俄罗斯方块
  • Analysis For Office的一些使用技巧
  • C++练级之初级:第六篇
  • 使用PyTorch和Flower 进行联邦学习
  • 重载new和delete
  • Flutter集成个推推送-安卓原生篇
  • 【电商必学】 WhatsApp 全新攻略:什么是交互式消息模板
  • 【Zookeeper源码走读】第一章 客户端与服务器的连接过程
  • 麓言信息设计创意思维,打开设计师思路
  • 智慧物流信息系统开发需具备哪些功能?
  • 2023北京老博会(中国国际老年产业博览会)展位预订迎高峰
  • 鸿蒙系统是什么?鸿蒙与开源鸿蒙的关系?鸿蒙系统的发展历程
  • H2O生成——屏障
  • 论文笔记:Model-Contrastive Federated Learning
  • TPM-TPM-Profile-PTP协议-2
  • Vue3事件绑定
  • 【五一创作】50道Java面试题
  • Python的一些知识
  • 做了一年csgo搬砖项目,还清所有债务:会赚钱的人都在做这件事 !
  • 更轻更好用的蓝牙耳机,日常佩戴更舒适,QCY Crossky Link体验
  • Nginx:常见的面试题和答案
  • Delphi 内存分配
  • Java程序猿搬砖笔记(十二)
  • 记录和传播知识的重要性不亚于创造知识本身【专利所保护的,主要是`流程`、`工艺`和`方法`,不是一个具体的产品。】