【Linux C 几种锁的性能对比】 1.读写锁 2.互斥锁 3.自旋锁 4.信号量 5.rcu

news2025/1/22 12:51:19

直接上代码
rcu.c

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

#include <pthread.h>
#include <limits.h>
#include <semaphore.h>
#include <urcu.h>


/* 1.读写锁
   2.互斥锁
   3.自旋锁
   4.信号量
   5.rcu
*/


#define RW_LOCK  0
#define MUTEX_LOCK  0
#define SPIN_LOCK 0
#define _SEM  0
#define URCU  1 


struct point{
	int x;
	int y;
};

struct point *gp;
int done = 0;
long reads = 0;
pthread_rwlock_t rwlock;
pthread_mutex_t mutex_t;
pthread_spinlock_t spinlock;
sem_t sem;

void *timer(void *arg){
	struct timespec ts, ts2;
	timespec_get(&ts, TIME_UTC);

	while(!done){
		
		sleep(1);
		timespec_get(&ts2, TIME_UTC);

		time_t sec = ts2.tv_sec - ts.tv_sec;

		printf("reads: %ld, %ld K reads/sec\n", reads, (reads/sec)/1000);
	}
}

void *updater(void *arg){
	struct point *p;
	struct point *old;
	int i = 0;
	for(i = 0; i< INT_MAX; i ++){

		p = malloc(sizeof(struct point));

		p->x = i;
		p->y = i+1;

		old = gp;
#if 0
		gp = p;
#elif RW_LOCK
		pthread_rwlock_wrlock(&rwlock);
		gp = p;
		pthread_rwlock_unlock(&rwlock);
#elif MUTEX_LOCK
		pthread_mutex_lock(&mutex_t);
		gp = p;
		pthread_mutex_unlock(&mutex_t);
#elif SPIN_LOCK 
		pthread_spin_lock(&spinlock);
		gp = p;
		pthread_spin_unlock(&spinlock);
#elif URCU
		rcu_assign_pointer(gp, p);
		synchronize_rcu();
#else 
		sem_wait(&sem);
		gp = p;
		sem_post(&sem);
#endif
		free(old);
	}
}

void *reader(void *arg){

	rcu_register_thread();//urcu

	while(!done){
		int x, y;
#if 0
		x = gp->x;
		y = gp->y;
#elif RW_LOCK 
		pthread_rwlock_rdlock(&rwlock);
		x = gp->x;
		y = gp->y;
		pthread_rwlock_unlock(&rwlock);
#elif MUTEX_LOCK   
		pthread_mutex_lock(&mutex_t);
		x = gp->x;
		y = gp->y;
		pthread_mutex_unlock(&mutex_t);
#elif SPIN_LOCK 
		pthread_spin_lock(&spinlock);
		x = gp->x;
		y = gp->y;
		pthread_spin_unlock(&spinlock);
#elif URCU
		rcu_read_lock();
		struct point *p = rcu_dereference(gp);
		x = p->x;
		y = p->y;
		rcu_read_unlock();
#else
		sem_wait(&sem);
		x = gp->x;
		y = gp->y;
		sem_post(&sem);

#endif
		
		reads ++;
		if(y != x+1){
			printf("Error: x:%d, y:%d\n", x, y);
			done = 1;
			break;
		}
		
	}
	rcu_unregister_thread();
	exit(1);

}
// gcc -o rcu rcu.c -lpthread -lurcu
int main(){

	pthread_t tid[3];

	pthread_rwlock_init(&rwlock, NULL);
	pthread_mutex_init(&mutex_t, NULL);
	pthread_spin_init(&spinlock, PTHREAD_PROCESS_SHARED);
	sem_init(&sem, 0, 1);
	rcu_init();//rcu
	
	gp = malloc(sizeof(struct point));
	gp->x = 1;
	gp->y = 2;
	
	pthread_create(&tid[0], NULL, updater, NULL);
	pthread_create(&tid[1], NULL, reader, NULL);
	pthread_create(&tid[2], NULL, timer, NULL);

	int i = 0;
	for(i = 0; i < 3; i ++){
		pthread_join(tid[i], NULL);	
	}
	
	free(gp);
	pthread_rwlock_destroy(&rwlock);
	pthread_mutex_destroy(&mutex_t);
	pthread_spin_destroy(&spinlock);
	return 0;
}

读写线程相当情况下 读写速度 对比
1.读写锁
rw
2.互斥锁
mutex
3.自旋锁
spin
4.信号量
sem
5.rcu
rcu
可以看出rcu读写性能优异 , 多线程同步不建议使用读写锁,嫌麻烦可以直接用互斥锁

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

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

相关文章

基于 Linux 的批量上传本地 Git 仓库到 Github 的实践

基于 Linux 的批量上传本地 Git 仓库到 Github 的实践 一、需求二、上传本地 Git 仓库2.1 初始版本2.2 优化版本 三、 GitHub 创建空仓库3.1 初始版本3.2 优化版本 四、Gitee 创建空仓库 一、需求 app目录下的每个文件夹都是一个git仓库&#xff0c;如何使用shell脚本将所有gi…

Python/R/GUI/BI类型常用数据可视化工具

什么是数据可视化工具&#xff1f; 数据可视化工具是指旨在可视化数据的所有形式的软件。它们处理数据输入&#xff0c;将其转换为用户可以根据自己的需求进行定制的视觉效果。 不同的工具可以包含不同的功能&#xff0c;但最基本的是&#xff0c;数据可视化工具提供输入数据集…

交叉编译含义

交叉编译是在一个平台上生成另一个平台上的可执行代码。同一个体系结构可以运行不同的操作系统&#xff1b;同样&#xff0c;同一个操作系统也可以在不同的体系结构上运行。 编译工具链下载&#xff1a; (1) ARM提供&#xff1a;Arm GNU Toolchain Downloads – Arm Develope…

GroundingDINO-根据文本提示检测任意目标

1. 背景介绍 GroundingDINO是一种新的SOTA零样本物体检测模型。在这篇文章中&#xff0c;我们将讨论Grounding DINO模型的优势&#xff0c;分析其具体的模型架构&#xff0c;并提供真实的测试样例。 闲话少说&#xff0c;我们直接开始吧&#xff01; 2.零样本目标检测 大多…

Python实现员工管理系统(Django页面版 ) 七

各位小伙伴们好久不见&#xff0c;2024年即将到来&#xff0c;小编在这里提前祝大家新的一年快快乐乐&#xff0c;能够事业有成&#xff0c;学习顺心&#xff0c;家庭和睦&#xff0c;事事顺利。 今天我们本篇要实现的是一个登录界面的实现&#xff0c;其实登录界面的实现看着挺…

php学习06-魔术常量

有九个魔术常量它们的值随着它们在代码中的位置改变而改变。例如 LINE 的值就依赖于它在脚本中所处的行来决定。这些特殊的常量不区分大小写&#xff0c;如下&#xff1a; 参考

SpringBoot知识

1、Spring和SpringBoot对比 2、版本调整 &#xff08;1&#xff09;先排除是否是JDK与SpringBoot的版本不一致导致的&#xff1a;如JDK1.8和SpringBoot3.1.5冲突&#xff1b; &#xff08;2&#xff09;调整编译版本 &#xff08;3&#xff09;调整maven的jdk &#xff08;4&…

AI又进化了,AI 写代码工具

今年 AI 的发展可谓一日千里&#xff0c;相信不少同学应该都用过 AI 来帮助自己提高开发效率吧&#xff1f; 比如让 AI 根据注释生成代码、解释整段代码、提供技术问题的答疑、修改 Bug、生成单元测试等等。 在 12 月 28 日刚刚结束的 WAVE SUMMIT 深度学习开发者大会上&…

引领手游技术潮流:武汉灰京文化的卓越技术创新与市场推广支持

在数字娱乐领域&#xff0c;手游行业正蓬勃发展&#xff0c;为数以亿计的玩家提供了丰富的娱乐选择。武汉灰京文化&#xff0c;作为该领域的佼佼者&#xff0c;以其强大的技术创新和全面的市场推广支持&#xff0c;为合作伙伴的成功铺平了道路&#xff0c;不仅提升了游戏质量&a…

Amlogic HDMI驱动分析

目录 一、简介 二、代码结构介绍 三、HDMI资料 四、宏观认识一下HDMI 1、硬件连接 2、Amlogic方案中HDMI的位置 3、Amlogic HDMI驱动模块的划分 五、HDMI-RX驱动分析 1、芯片手册解读 2、RX -makefile 3、驱动模型分析 4、RX的运行 5、HDMI RX调试 六、HDMI-TX驱…

单列集合Collection常用api

集合体系结构 Collection Collection是单列集合的祖宗接口&#xff0c;它的功能是全部单列集合都可以继承使用的。 public static void main(String[] args) {//TODO Collection类 所有集合的接口 /*public boolean add(E e) 添加public void clear() …

Ubuntu20.04 上启用 VCAN 用作本地调试

目录 一、启用本机的 VCAN​ 编辑 1.1 加载本机的 vcan 1.2 添加本机的 vcan0 1.3 查看添加的 vcan0 1.4 开启本机的 vcan0 1.5 关闭本机的 vcan0 1.6 删除本机的 vcan0 二、测试本机的 VCAN 2.1 CAN 发送数据 代码 2.2 CAN 接收数据 代码 2.3 CMakeLists.…

图像质量评估:使用 SSIM 计算图像相似性

在图像处理领域&#xff0c;衡量两幅图像之间相似性的一种常见方法是使用结构相似性指数&#xff08;SSIM&#xff09;。SSIM 是一种全参考的图像质量评估指标&#xff0c;它不仅考虑了图像的亮度、对比度&#xff0c;还考虑了结构信息。在本文中&#xff0c;我们将介绍一个使用…

Qt QAction添加图片

QAction用的时候&#xff0c;时常需要添加图片&#xff0c;如上图所示&#xff0c;代码如下所示&#xff1a; 测试的图片格式包含png,jpg,bmp,svg&#xff0c;其他未测试

OpenCV-Python(9):图像基础操作

目录 学习目标 获取图像像素并修改像素值 获取图像属性 图像ROI 拆分及合并图像通道 图像边缘扩充 学习目标 获取像素值并修改获取图像的属性(信息)图像的ROI获取图像通道拆分及合并图像扩边 获取图像像素并修改像素值 几乎所有这些操作与Numpy 的关系要比与OpenCV 的…

大语言模型(LLM)框架及微调 (Fine Tuning)

大语言模型&#xff08;LLM&#xff09; 技术作为人工智能领域的一项重要创 新在今年引起了广泛的关注。 LLM 是利用深度学习和大数据训练的人工智能系统&#xff0c;专门 设计来理解、生成和回应自然语言。这些模型通过分析大量 的文本数据来学习语言的结构和用法&#xff0c;…

跟着LearnOpenGL学习11--材质

文章目录 一、材质二、设置材质三、光的属性四、不同的光源颜色 一、材质 在现实世界里&#xff0c;每个物体会对光产生不同的反应。 比如&#xff0c;钢制物体看起来通常会比陶土花瓶更闪闪发光&#xff0c;一个木头箱子也不会与一个钢制箱子反射同样程度的光。 有些物体反…

器件的静态特性

器件的静态特性 静态特性&#xff08;伏安特性&#xff09; 1.器件在导通或关断的状态下&#xff0c;其电压与电流对应关系。 2.静态过程体现器件最基本的电压与电流稳态特性。 动态特性&#xff08;开关特性&#xff09; 1.器件在开或关过程中&#xff0c;其电压、电流随时…

关于java循环结构for

关于java循环结构for 在上一篇文章中&#xff0c;我们了解到了while和do…while的结构以及用法&#xff0c;这篇文章我们主要学习一下最常用的循环结构&#xff0c;for结构&#x1f600;&#xff0c;这个结构理解起来相对while结构会难一些&#xff0c;本篇文章内容会很多&…

深入Mybatis数据源

数据源是持久层框架中最核心的组件之一&#xff0c;在实际工作中比较常见的数据源有 C3P0、Apache Common DBCP、Proxool 等。作为一款成熟的持久化框架&#xff0c;MyBatis 不仅自己提供了一套数据源实现&#xff0c;而且还能够方便地集成第三方数据源。 javax.sql.DataSourc…