基本概念:
读写锁也叫做共享互斥锁。
当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞。当读写锁在读加锁状态,所有试图以读模式对它进行加锁的线程都可以得到访问权。
与互斥量相比,读写锁在使用之前必须初始化,在释放它们底层的内存之前必须销毁。
一、锁的初始化与销毁
PTHREAD_RWLOCK_DESTROY(P) POSIX Programmer's Manual PTHREAD_RWLOCK_DESTROY(P) NAME pthread_rwlock_destroy, pthread_rwlock_init - destroy and initialize a read-write lock object SYNOPSIS #include <pthread.h> int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); 两个函数的返回值:若成功,返回0;否则,返回错误编号二、读锁
PTHREAD_RWLOCK_RDLOCK(P) POSIX Programmer's Manual PTHREAD_RWLOCK_RDLOCK(P) NAME pthread_rwlock_rdlock, pthread_rwlock_tryrdlock - lock a read-write lock object for reading SYNOPSIS #include <pthread.h> int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); 两个函数的返回值:若成功,返回0;否则,返回错误编号 pthread_rwlock_tryrdlock函数可以获取锁时,返回0.否则,返回错误EBUSY三、写锁
PTHREAD_RWLOCK_TRYWRLOCK(P)POSIX Programmer's ManuaPTHREAD_RWLOCK_TRYWRLOCK(P) NAME pthread_rwlock_trywrlock, pthread_rwlock_wrlock - lock a read-write lock object for writing SYNOPSIS #include <pthread.h> int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); 两个函数的返回值:若成功,返回0;否则,返回错误编号pthread_rwlock_trywrlock函数可以获取锁时,返回0.否则,返回错误EBUSY
四、带有超时的读写锁
PTHREAD_RWLOCK_TIMEDWRLOCK(POSIX Programmer's ManPTHREAD_RWLOCK_TIMEDWRLOCK(P) NAME pthread_rwlock_timedrdlock - lock a read-write lock for reading pthread_rwlock_timedwrlock - lock a read-write lock for writing SYNOPSIS #include <pthread.h> #include <time.h> int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abs_timeout); int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rwlock, const struct timespec *restrict abs_timeout); 两个函数的返回值:若成功,返回0;否则,返回错误编号 如果它们不能获取锁,那么超时到期时,这两个函数将返回ETIMEDOUT五、解锁
PTHREAD_RWLOCK_UNLOCK(P) POSIX Programmer's Manual PTHREAD_RWLOCK_UNLOCK(P) NAME pthread_rwlock_unlock - unlock a read-write lock object SYNOPSIS #include <pthread.h> int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); 返回值:若成功,返回0;否则,返回错误编号读写锁属性:
读写锁支持的唯一属性是进程共享属性。它与互斥量的进程共享属性是相同的,这里不展开讨论。
例子:gcc pthread_rwlock.c -pthread
#include <pthread.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> static int num = 0; static int count = 100000; static pthread_rwlock_t rwlock; void Perror(const char *s) { perror(s); exit(EXIT_FAILURE); } 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_rwlock_wrlock(&rwlock); num += 1; pthread_rwlock_unlock(&rwlock); } } void* fun3(void *arg) { pthread_t thread_id = pthread_self(); printf("the thread3 id is %ld\n", (long)thread_id); int i = 1; for (; i<=count; ++i) { pthread_rwlock_wrlock(&rwlock); num += 1; pthread_rwlock_unlock(&rwlock); } } int main() { int err; pthread_t thread1; pthread_t thread2; pthread_t thread3; // init pthread_rwlock_init(&rwlock, NULL); thread1 = pthread_self(); printf("the thread1 id is %ld\n", (long)thread1); // Create thread err = pthread_create(&thread2, NULL, fun2, NULL); if (err != 0) { Perror("can't create thread2\n"); } err = pthread_create(&thread3, NULL, fun3, NULL); if (err != 0) { Perror("can't create thread3\n"); } // detach thread err = pthread_detach(thread2); if (err != 0) { Perror("can't detach thread2\n"); } err = pthread_detach(thread3); if (err != 0) { Perror("can't detach thread3\n"); } int i = 1; for (; i<=count; ++i) { pthread_rwlock_rdlock(&rwlock); int temp = num; pthread_rwlock_unlock(&rwlock); } sleep(10); printf("The num is %d\n", num); pthread_rwlock_destroy(&rwlock); return 0; }参考:《unix环境高级编程》·第三版
End;