Linux使用C语言实现通过互斥锁限制对共享资源的访问

news2025/4/8 11:35:06

互斥锁限制共享资源的访问

主线程中有两个线程,分别输出信息。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

int g_data=0;


void* fun1(void *arg)
{
        printf("t1:%ld thread is create\n", (unsigned long)pthread_self());
        printf("t1: %d\n", *((int*)arg));
        
        while(1){
                printf("t1:%d\n", g_data++);
                sleep(1);
        }
}

void* fun2(void *arg)
{
        printf("t2:%ld thread is create\n", (unsigned long)pthread_self());
        printf("t2: %d\n", *((int*)arg));
        while(1){
                printf("t2:%d\n", g_data++);
                sleep(1);
        }
}

int main()
{

        int ret;
        int param = 100;
        pthread_t t1;
        pthread_t t2;


        //                       线程属性 线程函数 线程函数参数
        ret = pthread_create(&t1, NULL, fun1, (void*)&param);
        if(ret == 0){
                printf("main:create t1 success\n");
        } else {
                perror("why t1 fail");
        }

        ret = pthread_create(&t2, NULL, fun2, (void*)&param);
        if(ret == 0){
                printf("main:create t1 success\n");
        } else {
                perror("why t2 fail");
        }

        printf("main:%ld\n", (unsigned long)pthread_self());//打印主线程ID

        while(1){
                printf("main:%d\n", g_data);
                sleep(1);
        }

        pthread_join(t1, NULL);//等待线程结束,防止进程结束,线程还未执行完毕
        pthread_join(t2, NULL);//等待线程结束,防止进程结束,线程还未执行完毕

        return 0;
}

如何能确保 3 一定在 线程1 中输出呢?我们就需要用到“锁”这个东西了。
一定要线程1 先运行 并且保证能输出3。
t1刚开始执行到while循环时候,就让它加锁,不让其它线程对共享资源访问【无论是否t2先执行,最终1s后都会轮到t1加锁,因为t2中释放锁后存在sleep函数,而t1没有】,循环一直执行,直到等到3 结束。因为当t1执行while循环时,t2就不能对g_data进行修改。

加锁后的修改:

//demo6
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

int g_data=0;
pthread_mutex_t mutex;

void* fun1(void *arg)
{
        printf("t1:%ld thread is create\n", (unsigned long)pthread_self());
        printf("t1: %d\n", *((int*)arg));
        pthread_mutex_lock(&mutex);
        while(1){
                printf("t1:%d\n", g_data++);
                sleep(1);
                if(g_data == 3){
                        pthread_mutex_unlock(&mutex);
                        printf("t1 quit================\n");
                        pthread_exit(NULL);
                }
        }
}

void* fun2(void *arg)
{
        printf("t2:%ld thread is create\n", (unsigned long)pthread_self());
        printf("t2: %d\n", *((int*)arg));
        while(1){
                printf("t2:%d\n", g_data);
                pthread_mutex_lock(&mutex);
                g_data++;
                pthread_mutex_unlock(&mutex);
                sleep(1);
        }
}

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("main:create t1 success\n");
        } else {
                perror("why t1 fail");
        }

        ret = pthread_create(&t2, NULL, fun2, (void*)&param);
        if(ret == 0){
                printf("main:create t1 success\n");
        } else {
                perror("why t2 fail");
        }

        printf("main:%ld\n", (unsigned long)pthread_self());//打印主线程ID

        while(1){
                printf("main:%d\n", g_data);
                sleep(1);
        }

        pthread_join(t1, NULL);//等待线程结束,防止进程结束,线程还未执行完毕
        pthread_join(t2, NULL);//等待线程结束,防止进程结束,线程还未执行完毕

        pthread_mutex_destroy(&mutex);
        return 0;
}

线程调用exit() 能让进程结束。所以线程中调用pthread_exit()函数

运行结果:可以看到,在t1中顺利退出,说明对互斥锁对共享资源的限制起作用了。
在这里插入图片描述

利用互斥锁对临界资源进行访问,主要是对全局变量的访问。为获取对共享资源的访问权限,t1线程是不断对全局变量访问,t2是做加法的时候才访问,而且加之后有1秒的延时。所以,t1肯定会先执行到3,即使t2先执行,也就执行一次,加一次就释放锁,t1还会拿到共享资源。
条件+互斥锁 更加智能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1478617.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

类和对象(2)——距离C++又近了一步

目录 一、构造函数 1.1声明和定义构造函数 1.2成员名和参数名 1.3构造函数的使用 1.4初始化列表 二、析构函数 2.1析构函数的概念 2.2析构函数的性质 三、拷贝构造函数 四、赋值运算符重载 4.1运算符重载 4.2赋值运算符重载 一、构造函数 我们知道&#xff0c;C中…

利用R语言进行因子分析实战(数据+代码+可视化+详细分析)

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

C++重新入门-string容器

目录 1.包含头文件 2.创建字符串 3.获取字符串长度 4.字符串拼接 5.字符串比较 相等性比较 大小比较 使用比较函数 6.访问字符串 7.查找子串 8.字符串修改 替换子串 插入字符或子串 删除字符或子串 9.提取子串 10.总结 当谈到C中的字符串时&#xff0c;std::str…

蓝桥杯刷题3

目录: 1. 天干地支 2. 明明的随机数 3. ISBN号码 4. 缩位求和 5. 幸运数字 6. 串的处理 7. 最长递增 8. 灌溉 9. 特殊日期 10. 最大距离 1. 天干地支 import java.util.*;public class Main {public static void main(String[] args) {Scanner scan new Scanner(Sys…

spring boot集成Elasticsearch 7.16.3

环境&#xff1a;Elasticsearch 版本 7.16.3 Elasticsearch for windows下载地址 windows 若依 spring boot版本 2.6.0 pom文件添加 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch<…

Automated Testing for LLMOps 01:使用CircleCI进行持续集成CI

Automated Testing for LLMOps 这是学习https://www.deeplearning.ai/short-courses/automated-testing-llmops/ 这门课的笔记 Learn how LLM-based testing differs from traditional software testing and implement rules-based testing to assess your LLM application. …

Java实战:构建高效预报名管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

基于transform的scale属性,动态缩放整个页面,实现数据可视化大屏自适应,保持比例不变形,满足不同分辨率的需求

文章目录 一、需求背景&#xff1a;二、需求分析&#xff1a;三、选择方案&#xff1a;四、实现代码&#xff1a;五、效果预览&#xff1a;六、封装组件&#xff1a; 一、需求背景&#xff1a; 数据可视化大屏是一种将数据、信息和可视化效果集中展示在一块或多块大屏幕上的技…

GL绘制自定义线条4_使用OpenGL ES实现钢笔效果

在以前的文章里http://t.csdnimg.cn/TgCtl&#xff0c;我简述了如何使用OpenGL ES实现光滑的粗线条的绘制效果&#xff0c;在闲暇时间我把它再进一步进化&#xff0c;实现了端点长度按照压感大小实现伸缩的逻辑&#xff0c;从而实现了如下的笔锋效果&#xff1a; 书写过程中的效…

MCBPS配置成SPI

MCBPS配置成SPI 典型的SPI接口 McBSP作为SPI主机 以McBSP为主的SPI接口如图所示。当McBSP被配置为主控器时,发送输出信号(DX)被用作SPI协议的SPISIMO信号,并且接收输入信号(DR)被用作SPISOMI信号。 表列出了将McBSP配置为主控器所需的寄存器位值。下表是有关配置要求…

动环监控是什么?为什么说它是3d可视化机房的眼睛?

在信息化时代的背景下&#xff0c;数据中心机房的重要性日益凸显&#xff0c;传统的人工管理模式显然已经无法应对持续增长的机房数量和规模、日益复杂的网络、频繁更新迭代的资产硬件......搭建3d可视化机房成为了许多企事业单位的共同选择。想要搭建3d可视化机房&#xff0c;…

iOS中卡顿产生的主要原因及优化思路

卡顿本质上是一个UI体验上的问题&#xff0c;而UI的渲染及显示&#xff0c;主要涉及CPU和GPU两个层面。若 CPUGPU渲染耗时超过16.7ms&#xff0c;就会在屏幕vsync信号到来时无法更新屏幕内容&#xff0c;进而导致卡顿。 iOS中UI渲染主要包含Layout->Draw->Prepare->Co…

在原有项目进行业务逻辑开发:同一用户短时间不得提交多次申请,以及更新主表时数据刷新掉了角色权限以及密码重置的问题,详细思路及代码

开发背景&#xff1a; 用户提交表单后&#xff0c;插入到对应数据库表的字段中去&#xff0c;因需要保存是哪一个用户提交的&#xff0c;所以需要拿到主表的user_id&#xff0c;更新功能为记录提交时间&#xff0c;短时间不得再次提交 在对一个已有角色权限分配&#xff0c;登录…

蓝牙耳机和笔记本电脑配对连接上了,播放设备里没有显示蓝牙耳机这个设备,选不了输出设备

环境&#xff1a; WIN10 杂牌蓝牙耳机6s 问题描述&#xff1a; 蓝牙耳机和笔记本电脑配对连接上了&#xff0c;播放设备里没有显示蓝牙耳机这个设备&#xff0c;选不了输出设备 解决方案&#xff1a; 1.打开设备和打印机&#xff0c;找到这个设备 2.选中这个设备&#…

【iOS ARKit】协作 Session 实例

协作 Session 使用注意事项 协作 Session 是在 ARWorldMap 基础上发展起来的技术&#xff0c;ARWorldMap 包含了一系列的地标、ARAnchor 及在观察这些地标和 ARAnchor 时摄像机的视场&#xff08;View&#xff09;。如果用户在某一个位置新创建了一个 ARAnchor&#xff0c;这时…

C++之善用const修饰成员函数

C之善用const修饰成员函数 文章目录 C之善用const修饰成员函数前言1. 约束函数对成员变量的修改2. 允许 const 对象调用3. 在重载函数中提供重载决策总结 前言 ​ 在C编程中&#xff0c;使用const修饰成员函数是一种非常重要的技术手段&#xff0c;它能够提高代码的可维护性、…

基于Python微博舆情数据爬虫可视化分析系统+可视化+情感分析+爬虫+机器学习(完整系统源码+数据库+详细文档)

文章目录 基于Python微博舆情数据爬虫可视化分析系统可视化情感分析爬虫机器学习&#xff08;完整系统源码数据库详细文档&#xff09;源码资料获取在文章末尾1、项目介绍 Pycharm介绍Python语言Echarts简介Navicat Premium 15简介MySQL简介Flask简介 2、项目界面UI详情源码资料…

事物管理(黑马学习笔记)

事物回顾 在数据库阶段我们已学习过事务了&#xff0c;我们讲到&#xff1a; 事物是一组操作的集合&#xff0c;它是一个不可分割的工作单位。事务会把所有的操作作为一个整体&#xff0c;一起向数据库提交或者是撤销操作请求。所以这组操作要么同时成功&#xff0c;要么同时…

Windows PowerShell 命令行历史记录补全

Windows 命令行历史记录补全 使用 powershell 安装PSReadLine 2.1.0 Install-Module PSReadLine -RequiredVersion 2.1.0检查是否存在配置文件 Test-path $profile # 为 false 则执行命令创建 New-item –type file –force $profile编辑配置文件 notepad $profile# 输入如下…

springboot 实现本地文件存储

springboot 实现本地文件存储 实现过程 上传文件保存文件&#xff08;本地磁盘&#xff09;返回文件HTTP访问服务器路径给前端&#xff0c;进行效果展示 存储 服务端接收上传的目的是提供文件的访问服务&#xff0c;对于SpringBoot而言&#xff0c;其对静态资源访问提供了很…