线程同步方式---3 读写锁
读写锁对比互斥锁好处是:
1)高并行性,读写锁根据线程对资源的操作类型分为 读 和 写,分别上锁,能够提高访问效率。而不是像互斥锁一样,不分读还是写操作,上锁之后其他进程都不能访问。如果当前临界区上了读锁,之后的写锁会阻塞。知道获得临界区,那么之后的读锁也会阻塞,可以防止写锁饥饿。
2)如果写锁占领了临界区,那么之后不管写锁还是读锁都会阻塞。
一个上了读写锁的例子,4个进程,2读2写。1个临界资源 global_num
/* * 4 threads 2 threads read lock 2 threads write lock * Observe sequence order */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; int global_num = 10; void err_exit(const char* err_msg) { printf("error: %s\n", err_msg); exit(1); } void *thread_read_lock( void *arg) { char *pthr_name = (char *) arg; while(1) { // read lock pthread_rwlock_rdlock(&rwlock); printf("thread: %s entered in critical area, global_num=%d\n", pthr_name, global_num); sleep(1); printf("thread: %s leaving from critical area...\n", pthr_name); // read unlock pthread_rwlock_unlock(&rwlock); sleep(1); } return NULL; } void *thread_write_lock( void *arg) { char *pthr_name = (char *)arg; while(1){ // write lock pthread_rwlock_wrlock(&rwlock); // write op global_num ++; printf("thread: %s entered in critical area, global_num = %d\n", pthr_name, global_num); sleep(1); printf("thread: %s leaving from area\n", pthr_name); // write unlock pthread_rwlock_unlock(&rwlock); sleep(2); } return NULL; } int main(void) { pthread_t tid_read_1, tid_read_2, tid_write_1, tid_write_2; if(pthread_create(&tid_read_1, NULL, thread_read_lock, (void *)"read_1") ) err_exit("create tid_read_1"); if(pthread_create(&tid_read_2, NULL, thread_read_lock, (void *)"read_1") ) err_exit("create tid_read_2"); if(pthread_create(&tid_write_1, NULL, thread_write_lock, (void *)"write_1") ) err_exit("create tid_write_1"); if(pthread_create(&tid_write_2, NULL, thread_write_lock, (void *)"write_2") ) err_exit("create tid_write_2"); // wait any thread in case of process terminating early if(pthread_join(tid_read_1, NULL)) err_exit("pthread_join()"); return 0; }
上面的都是阻塞锁:
#include <pthread.h> int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
非阻塞锁
#include <pthread.h> #include <time.h> int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); 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);