原文的地址在http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/
还有一些相关资料,在这里:
https://computing.llnl.gov/tutorials/pthreads/
http://linux.die.net/man/3/pthread_rwlock_tryrdlock
http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_rwlock_init.html
作者在文中对于spinlock和mutex进行了比较,但是还有rwlock呢,他没有比较,那么测试代码如下,比较一下这三个锁:
#include <stdio.h> #include <unistd.h> #include <sys/syscall.h> #include <errno.h> #include <sys/time.h> #include <list> #include <pthread.h> #define LOOPS 5000000 using namespace std; list<int> the_list; #ifdef USE_SPINLOCK pthread_spinlock_t spin_lock; #elif USE_RWLOCK pthread_rwlock_t rw_lock; #else pthread_mutex_t mutex_lock; #endif //Get the thread id pid_t gettid() { return syscall( __NR_gettid ); } void *consumer(void *ptr){ int i; printf("Consumer TID %lun", (unsigned long)gettid()); while (1){ #ifdef USE_SPINLOCK pthread_spin_lock(&spin_lock); #elif USE_RWLOCK pthread_rwlock_wrlock( &rw_lock ); // pthread_rwlock_rdlock( &rw_lock ); #else pthread_mutex_lock(&mutex_lock); #endif if (the_list.empty()){ #ifdef USE_SPINLOCK pthread_spin_unlock(&spin_lock); #elif USE_RWLOCK pthread_rwlock_unlock( &rw_lock); #else pthread_mutex_unlock(&mutex_lock); #endif break; } i = the_list.front(); the_list.pop_front(); #ifdef USE_SPINLOCK pthread_spin_unlock(&spin_lock); #elif USE_RWLOCK pthread_rwlock_unlock( &rw_lock); #else pthread_mutex_unlock(&mutex_lock); #endif } return NULL; } int main(void){ pthread_t tid_0, tid_1; struct timeval tv_0, tv_1; #ifdef USE_SPINLOCK pthread_spin_init( &spin_lock, 0 ); #elif USE_RWLOCK pthread_rwlock_init( &rw_lock, NULL); #else pthread_mutex_init( &mutex_lock, NULL ); #endif //init the lsit int i; for(i=0; i<LOOPS; i++){ the_list.push_back(i); } gettimeofday(&tv_0, NULL); pthread_create(&tid_0, NULL, consumer, NULL); pthread_create(&tid_1, NULL, consumer, NULL); // pthread_join(tid_0, NULL); pthread_join(tid_1, NULL); // gettimeofday(&tv_1, NULL); timersub(&tv_1, &tv_0, &tv_1); printf("timing result: secs=%d, usec=%d ", tv_1.tv_sec, tv_1.tv_usec); #ifdef USE_SPINLOCK pthread_spin_destroy(& spin_lock ); #elif USE_RWLOCK pthread_rwlock_destroy( &rw_lock); #else pthread_mutex_destroy(&mutex_lock); #endif return 0; }
这里的测试代码是基本采用了原文的代码,然后添加进入了对于rwlock的测试代码;
各个锁性能测试结果如下:
$lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 12.04.3 LTS
Release: 12.04
Codename: precise
$time ./spinlock
Consumer TID 11602nConsumer TID 11603ntiming result: secs=0, usec=585267
real 0m1.017s
user 0m1.512s
sys 0m0.060s
$time ./mutex
Consumer TID 11586nConsumer TID 11585ntiming result: secs=1, usec=22265
real 0m5.783s
user 0m1.068s
sys 0m1.244s
$time ./rwlock
Consumer TID 11596nConsumer TID 11595ntiming result: secs=1, usec=381404
real 0m1.864s
user 0m1.436s
sys 0m1.516s
time 命令的输出格式简单介绍一下:
S: Total number of CPU-seconds used by the system on behalf of the process (in kernel mode), in seconds.
U: Total number of CPU-seconds that the process used directly (in user mode), in seconds.
P: Percentage of the CPU that this job got. This is just user + system times divided by the total running time. It also prints a percent‐age sign.