mutex、读写锁、自旋锁、信号量以及RCU的性能测试
前言
本例为一个读线程和一个写线程,在不同加锁情况下测试一秒钟读写次数
没有测试多线程情况,结果只有参考意义
读写次数还与cpu频率相关 但大致不同种类的锁性能比较差距不大
测试源码和过程在最下面
一、直接上结论
1、以下为每秒读写次数
次数与cpu频率相关,不同机器测试结果不同(这里使用ubuntu20.04虚拟机测试的)
读写锁 21000k
mutex 31000k
自旋锁 58000k
信号量 27000k
rcu 47000k
2、锁的特点和使用场景
自旋锁特点 循环等待等 力度很小 用于链表头指针改变等情况
mutex 加锁时线程休眠一会看一下 可用于大部分情况
读写锁 读写都要判断 加锁复杂 不推荐使用
信号量 pv操作 比mutex低一点
rcu 读写锁变种 read copy update 可以代替读写锁情况
二、环境准备
编译命令
gcc -o rcu rcu.c -lpthread -lurcu
rcu锁需要安装liburcu-dev
apt-get install liburcu-dev
三、实际测试结果
不加锁
root@luo:~/workspace/test# ./rcu
Error: x:2340421, y:3524383
读写锁
root@luo:~/workspace/test# ./rcu
reads: 19500709, 19500 K reads/sec
reads: 44758029, 22379 K reads/sec
reads: 65393430, 21797 K reads/sec
reads: 85189522, 21297 K reads/sec
信号量
root@luo:~/workspace/test# ./rcu
reads: 27627678, 27627 K reads/sec
reads: 55094966, 27547 K reads/sec
reads: 82395410, 27465 K reads/sec
reads: 109609817, 27402 K reads/sec
mutex
root@luo:~/workspace/test# ./rcu
reads: 32018261, 32018 K reads/sec
reads: 63767452, 31883 K reads/sec
reads: 95838658, 31946 K reads/sec
reads: 127792109, 31948 K reads/sec
自旋锁
root@luo:~/workspace/test# ./rcu
reads: 57844075, 57844 K reads/sec
reads: 117047083, 58523 K reads/sec
reads: 173215973, 57738 K reads/sec
reads: 229239811, 57309 K reads/sec
RCU
root@luo:~/workspace/test# ./rcu
reads: 47511136, 47511 K reads/sec
reads: 94736084, 47368 K reads/sec
reads: 141648406, 47216 K reads/sec
reads: 188779939, 47194 K reads/sec
四、 源码
rcu.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <limits.h>
#include <semaphore.h>
#include <urcu.h>
struct point {
int x;
int y;
};
struct point *gp;
int done = 0;
long reads = 0;
pthread_rwlock_t rwlock;
pthread_mutex_t mutex;
pthread_spinlock_t spinlock;
sem_t sem;
void *timer(void *arg)