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

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

直接上代码

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.读写锁

2.互斥锁

3.自旋锁

4.信号量

5.rcu

可以看出rcu读写性能优异 , 多线程同步不建议使用读写锁,嫌麻烦可以直接用互斥锁

相关文章
|
8天前
|
缓存 算法 Linux
深入理解Linux内核调度器:公平性与性能的平衡####
真知灼见 本文将带你深入了解Linux操作系统的核心组件之一——完全公平调度器(CFS),通过剖析其设计原理、工作机制以及在实际系统中的应用效果,揭示它是如何在众多进程间实现资源分配的公平性与高效性的。不同于传统的摘要概述,本文旨在通过直观且富有洞察力的视角,让读者仿佛亲身体验到CFS在复杂系统环境中游刃有余地进行任务调度的过程。 ####
28 6
|
3月前
|
缓存 监控 网络协议
掌控全局:Linux 系统性能调优技巧全面指南
掌控全局:Linux 系统性能调优技巧全面指南
|
8天前
|
监控 网络协议 算法
Linux内核优化:提升系统性能与稳定性的策略####
本文深入探讨了Linux操作系统内核的优化策略,旨在通过一系列技术手段和最佳实践,显著提升系统的性能、响应速度及稳定性。文章首先概述了Linux内核的核心组件及其在系统中的作用,随后详细阐述了内存管理、进程调度、文件系统优化、网络栈调整及并发控制等关键领域的优化方法。通过实际案例分析,展示了这些优化措施如何有效减少延迟、提高吞吐量,并增强系统的整体健壮性。最终,文章强调了持续监控、定期更新及合理配置对于维持Linux系统长期高效运行的重要性。 ####
|
16天前
|
人工智能 安全 Linux
|
1月前
|
存储 缓存 监控
Linux中内存和性能问题
【10月更文挑战第5天】
38 4
|
1月前
|
存储 监控 固态存储
Linux中提高性能
【10月更文挑战第6天】
33 2
|
1月前
|
安全 Linux
Linux线程(十一)线程互斥锁-条件变量详解
Linux线程(十一)线程互斥锁-条件变量详解
|
3月前
|
消息中间件 Linux 开发者
Linux进程间通信秘籍:管道、消息队列、信号量,一文让你彻底解锁!
【8月更文挑战第25天】本文概述了Linux系统中常用的五种进程间通信(IPC)模式:管道、消息队列、信号量、共享内存与套接字。通过示例代码展示了每种模式的应用场景。了解这些IPC机制及其特点有助于开发者根据具体需求选择合适的通信方式,促进多进程间的高效协作。
158 3
|
2月前
|
Linux
linux内核 —— 读写信号量实验
linux内核 —— 读写信号量实验
|
3月前
|
开发者 API Windows
从怀旧到革新:看WinForms如何在保持向后兼容性的前提下,借助.NET新平台的力量实现自我进化与应用现代化,让经典桌面应用焕发第二春——我们的WinForms应用转型之路深度剖析
【8月更文挑战第31天】在Windows桌面应用开发中,Windows Forms(WinForms)依然是许多开发者的首选。尽管.NET Framework已演进至.NET 5 及更高版本,WinForms 仍作为核心组件保留,支持现有代码库的同时引入新特性。开发者可将项目迁移至.NET Core,享受性能提升和跨平台能力。迁移时需注意API变更,确保应用平稳过渡。通过自定义样式或第三方控件库,还可增强视觉效果。结合.NET新功能,WinForms 应用不仅能延续既有投资,还能焕发新生。 示例代码展示了如何在.NET Core中创建包含按钮和标签的基本窗口,实现简单的用户交互。
67 0