红联Linux门户
Linux帮助

linux多线程之自旋锁

发布时间:2016-08-16 15:31:43来源:linux网站作者:带鱼兄
基本概念:
何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。
 
一、初始化和销毁锁
PTHREAD_SPIN_DESTROY(P)POSIX Programmer's Manual   PTHREAD_SPIN_DESTROY(P)
NAME  
pthread_spin_destroy,  pthread_spin_init - destroy or initialize a spin  
lock object (ADVANCED REALTIME THREADS)
SYNOPSIS  
#include <pthread.h>  
int pthread_spin_destroy(pthread_spinlock_t *lock);  
int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
两个函数的返回值:若成功,返回0;否则,返回错误编号
关于pthread_spin_init函数的参数pshard,单进程可以设置成PTHREAD_PROCESS_SHARED
 
二、加锁与解锁
PTHREAD_SPIN_LOCK(P)   POSIX Programmer's Manual  PTHREAD_SPIN_LOCK(P) 
NAME  
pthread_spin_lock,  pthread_spin_trylock  -  lock  a  spin  lock object  
(ADVANCED REALTIME THREADS)
SYNOPSIS  
#include <pthread.h>  
int pthread_spin_lock(pthread_spinlock_t *lock);  
int pthread_spin_trylock(pthread_spinlock_t *lock);  
int pthread_spin_unlock(pthread_spinlock_t *lock);
两个函数的返回值:若成功,返回0;否则,返回错误编号
 
例子1,互斥锁的耗时, gcc pthread_mutex.c -pthread -o mutex:
#include <pthread.h>  
#include <stdio.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <errno.h>  
#include <sys/timeb.h>
static int num = 0;  
static int count = 10000000;  
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void Perror(const char *s)  
{  
perror(s);  
exit(EXIT_FAILURE);  
}
long long getSystemTime() {  
struct timeb t;  
ftime(&t);  
return 1000 * t.time + t.millitm;  
}
void* fun2(void *arg)  
{  
pthread_t thread_id = pthread_self();  
printf("the thread2 id is %ld\n", (long)thread_id);  
int i = 1;  
for (; i<=count; ++i) {  
pthread_mutex_lock(&mutex);  
num += 1;  
pthread_mutex_unlock(&mutex);  
}  
}
int main()  
{  
int err;  
pthread_t thread1;  
pthread_t thread2;
thread1 = pthread_self();  
printf("the thread1 id is %ld\n", (long)thread1);
long long start = getSystemTime();
// Create thread  
err = pthread_create(&thread2, NULL, fun2, NULL);  
if (err != 0) {  
Perror("can't create thread2\n");  
}
int i = 1;  
for (; i<=count; ++i) {  
pthread_mutex_lock(&mutex);  
num += 1;  
pthread_mutex_unlock(&mutex);  
}
pthread_join(thread2, NULL);  
long long end = getSystemTime();
printf("The num is %d, pay %lld ms\n", num, (end-start));
return 0;  
}  
 
例子2,自旋锁的耗时,gcc pthread_spin.c -pthread -o spin:
#include <pthread.h>  
#include <stdio.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <errno.h>  
#include <sys/timeb.h>
static int num = 0;  
static int count = 10000000;  
static pthread_spinlock_t spin;
void Perror(const char *s)  
{  
perror(s);  
exit(EXIT_FAILURE);  
}
long long getSystemTime() {  
struct timeb t;  
ftime(&t);  
return 1000 * t.time + t.millitm;  
}
void* fun2(void *arg)  
{  
pthread_t thread_id = pthread_self();  
printf("the thread2 id is %ld\n", (long)thread_id);  
int i = 1;  
for (; i<=count; ++i) {  
pthread_spin_lock(&spin);  
num += 1;  
pthread_spin_unlock(&spin);  
}  
}
int main()  
{  
int err;  
pthread_t thread1;  
pthread_t thread2;
pthread_spin_init(&spin, PTHREAD_PROCESS_PRIVATE);
thread1 = pthread_self();  
printf("the thread1 id is %ld\n", (long)thread1);
long long start = getSystemTime();
// Create thread  
err = pthread_create(&thread2, NULL, fun2, NULL);  
if (err != 0) {  
Perror("can't create thread2\n");  
}
int i = 1;  
for (; i<=count; ++i) {  
pthread_spin_lock(&spin);  
num += 1;  
pthread_spin_unlock(&spin);  
}
pthread_join(thread2, NULL);  
long long end = getSystemTime();
printf("The num is %d, pay %lld ms\n", num, (end-start));  
pthread_spin_destroy(&spin);  
return 0;  
}  
 
运行结果,可以看到某些条件下,自旋锁是比较快的:
linux多线程之自旋锁
 
参考:《unix环境高级编程》·第三版
 
本文永久更新地址:http://www.linuxdiyf.com/linux/23369.html