直接上代码
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读写性能优异 , 多线程同步不建议使用读写锁,嫌麻烦可以直接用互斥锁