【Linux多线程编程】互斥锁及其使用
1、互斥锁
用于解决竞争问题的一种机制。
什么是竞争,竞争就是多个实体同时获取一个资源,例如多个线程写一个全局变量。
2、Linux如何使用互斥锁
以pthread为例,锁的创建和使用如下:
/* 创建锁 */
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;/* 加锁*/
pthread_mutex_lock(&lock);/* 解锁 */
pthread_mutex_unlock(&lock);
3、多写者问题
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <pthread.h>/* global variable */
int gValue = 0;pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;void *threadFuncReader(void *arg)
{while(1){gValue = 1;if(1 != gValue){printf("\nerror");}// printf("\nthis is [1], read value is [%d]", gValue);usleep(1);}}void *threadFuncWriter(void *arg)
{while(1){gValue = 2;if(2 !=gValue ){printf("\nerror");}else{// printf("\nthis is [2], read value is [%d]", gValue); }usleep(1);}}void *threadFuncWriter1(void *arg)
{while(1){gValue = 3;if(3 != gValue ){printf("\nerror");}else{//printf("\nthis is [3], read value is [%d]", gValue); }usleep(1);}}void *threadFuncWriter2(void *arg)
{while(1){gValue = 4;if(4 != gValue ){printf("\nerror");}else{printf("\nthis is [4], read value is [%d]", gValue); }sleep(1);}}int main(int argc, int **argv)
{/* shared resources */pthread_t tid_reader;pthread_t tid_writer;pthread_t tid_writer1;pthread_t tid_writer2;pthread_create(&tid_reader, NULL, threadFuncReader, NULL);pthread_create(&tid_writer, NULL, threadFuncWriter, NULL);pthread_create(&tid_writer1, NULL, threadFuncWriter1, NULL);pthread_create(&tid_writer2, NULL, threadFuncWriter2, NULL);pthread_join(tid_reader, NULL);pthread_join(tid_writer, NULL);pthread_join(tid_writer1, NULL);pthread_join(tid_writer2, NULL);printf("\n hello world in Linux.");return 0;
}
上述代码由于没有锁,运行结果如下:
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
error
this is [4], read value is [4]
加锁后的代码:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <pthread.h>/* global variable */
int gValue = 0;pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;void *threadFuncReader(void *arg)
{while(1){pthread_mutex_lock(&lock);gValue = 1;if(1 != gValue){printf("\nerror");}// printf("\nthis is [1], read value is [%d]", gValue);pthread_mutex_unlock(&lock);usleep(1);}}void *threadFuncWriter(void *arg)
{while(1){pthread_mutex_lock(&lock);gValue = 2;if(2 !=gValue ){printf("\nerror");}else{// printf("\nthis is [2], read value is [%d]", gValue); }pthread_mutex_unlock(&lock);usleep(1);}}void *threadFuncWriter1(void *arg)
{while(1){pthread_mutex_lock(&lock);gValue = 3;if(3 != gValue ){printf("\nerror");}else{//printf("\nthis is [3], read value is [%d]", gValue); }pthread_mutex_unlock(&lock);usleep(1);}}void *threadFuncWriter2(void *arg)
{while(1){pthread_mutex_lock(&lock);gValue = 4;if(4 != gValue ){printf("\nerror");}else{printf("\nthis is [4], read value is [%d]", gValue); }pthread_mutex_unlock(&lock);sleep(1);}}int main(int argc, int **argv)
{/* shared resources */pthread_t tid_reader;pthread_t tid_writer;pthread_t tid_writer1;pthread_t tid_writer2;pthread_create(&tid_reader, NULL, threadFuncReader, NULL);pthread_create(&tid_writer, NULL, threadFuncWriter, NULL);pthread_create(&tid_writer1, NULL, threadFuncWriter1, NULL);pthread_create(&tid_writer2, NULL, threadFuncWriter2, NULL);pthread_join(tid_reader, NULL);pthread_join(tid_writer, NULL);pthread_join(tid_writer1, NULL);pthread_join(tid_writer2, NULL);printf("\n hello world in Linux.");return 0;
}
运行结果:
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
this is [4], read value is [4]
相关文章:
【Linux多线程编程】互斥锁及其使用
1、互斥锁 用于解决竞争问题的一种机制。 什么是竞争,竞争就是多个实体同时获取一个资源,例如多个线程写一个全局变量。 2、Linux如何使用互斥锁 以pthread为例,锁的创建和使用如下: /* 创建锁 */ pthread_mutex_t lock PTHR…...

RabbitMQ_00000
MQ的相关概念 RabbitMQ官网地址:https://www.rabbitmq.com RabbitMQ API地址:https://rabbitmq.github.io/rabbitmq-java-client/api/current/ 什么是MQ? MQ(message queue)本质是个队列,FIFO先入先出,只不过队列中…...
【linux】docker下homeassistant和nodered安装及配置
1、homeassistant安装 从 Docker Hub 上拉取 Home Assistant 的镜像文件 docker pull homeassistant/home-assistant 是运行 Home Assistant 容器 docker run -id --name"homeassistant" --privileged --restart always -p 8123:8123 -e TZAisa/Shanghai --nethost…...

Qt扩展-muParser数学公式解析
muParser数学公式解析 一、概述1. 针对速度进行了优化2. 支持的运算符3. 支持的函数4. 用户定义的常量5. 用户定义的变量6. 自定义值识别回调7. 其他功能 二、内置函数三、内置二元运算符四、三元运算符五、内置常量六、源码引入1. 源码文件2. 编译器开关1. MUP_BASETYPE2.MUP_…...

【Matplotlib】figure方法之图形的保存
🎈个人主页:甜美的江 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:matplotlib 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进…...
数据库管理-第142期 DBA?DBA!(20240131)
数据库管理142期 2024-01-31 数据库管理-第142期 DBA?DBA!(20240131)正文总结 数据库管理-第142期 DBA?DBA!(20240131) 作者:胖头鱼的鱼缸(尹海文)…...

react 之 zustand
zustand可以说是redux的平替 官网地址:https://zustand-demo.pmnd.rs/ 1.安装 npm i zustand2.基础使用 // zustand import { create } from zustand// 1. 创建store // 语法容易出错 // 1. 函数参数必须返回一个对象 对象内部编写状态数据和方法 // 2. set是用来…...
leetcode-回文链表
234. 回文链表 在此对比的值,不是节点 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def isPalindrome(self, head: Optional[ListNod…...
Pinia:一个Vue的状态管理库
Pinia的使用方法包括以下步骤: 安装Pinia:通过yarn或npm进行安装: yarn命令: yarn add pinianpm命令: npm install pinia创建根存储:在main.ts中引入Pinia插件,并创建一个根存储。这可以通过创建…...

2024 Flutter 重大更新,Dart 宏(Macros)编程开始支持,JSON 序列化有救
说起宏编程可能大家并不陌生,但是这对于 Flutter 和 Dart 开发者来说它一直是一个「遗憾」,这个「遗憾」体现在编辑过程的代码修改支持上,其中最典型的莫过于 Dart 的 JSON 序列化。 举个例子,目前 Dart 语言的 JSON 序列化高度依…...

云计算概述(云计算类型、技术驱动力、关键技术、特征、特点、通用点、架构层次)(二)
云计算概述(二) (云计算类型、技术驱动力、关键技术、特征、特点、通用点、架构层次) 目录 零、00时光宝盒 一、云计算类型(以服务的内容或形态来分) 二、云计算的12种技术驱动力 三、云计算的关键技术 四、云计…...

物流平台架构设计与实践
随着电商行业的迅猛发展,物流行业也得到了极大的发展。从最初的传统物流到现在的智慧物流,物流技术和模式也在不断的更新与升级。物流平台作为连接电商和物流的重要媒介,其架构设计和实践显得尤为重要。 一、物流平台架构设计 1. 前端架构设…...

RedHat8.4安装邮件服务器
一、配置发件服务器 1.1 根据现场IP,配置主机名 vim /etc/hosts 192.168.8.120 mail.test.com 将主机名更改为邮件服务器域名mail.test.com 1.2 关闭防火墙,禁止开机启动 systemctl stop firewalld systemctl disable firewalld 1.3 关闭selinux v…...

Linux Shell系列--dirname 去除基本文件名
一、目的 上一篇中我们介绍了basename命令的使用,本篇我们介绍dirname命令,dirname 命令与 basename 互补,它负责删除路径中的基本文件名部分(包括扩展名),只保留目录部分。 二、介绍 dirname首先去除字符…...

池化技术的总结
文章目录 1.什么是池化技术2.池化技术的应用一、连接池二、线程池三、内存池 3.池化技术的总结 1.什么是池化技术 池化技术指的是提前准备一些资源,在需要时可以重复使用这些预先准备的资源。 在系统开发过程中,我们经常会用到池化技术。通俗的讲&am…...

H5简约星空旋转引导页源码
H5简约星空旋转引导页源码 源码介绍:一款带有星空旋转背景特效的源码,带有四个按钮 下载地址: https://www.changyouzuhao.cn/11655.html...
前端学习之路(4) vue2和vue3的区别
一. 根节点不同 vue2中必须要有根标签vue3中可以没有根标签,会默认将多个根标签包裹在一个fragement虚拟标签中,有利于减少内存。 二. 组合式API和选项式API 在vue2中采用选项式API,将数据和函数集中起来处理,将功能点切割了当…...

网络原理-TCP/IP(5)
TCP协议 延迟应答 它也是基于滑动窗口,提高效率的一种机制,结合滑动窗口以及流量控制,能够以延迟应答ACK的方式,把反馈的窗口,搞大.核心在于允许范围内,让窗口尽可能大. 如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小. 1.假设接收端缓冲区为1M.一次收到了5…...
Docker 常用命令详细介绍
Docker 是一个开源的应用容器引擎,它允许开发者打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。Docker 使用概率最高的命令…...

10G PON演进到50G PON
10G-PON是万兆无源光网络,光纤链路传输速率能够达到10Gbps。根据ZTE的报告称,截至2023年6月,全球10G PON出货量已超过3000万个PON端口,其中中国市场份额约占80%。 10G PON在中国市场的广泛部署,显着推进了10G PON产业链…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...