在对数据的读写应用中,更多的是读操作,而写操作较少,例如对数据库数据的读写 应用。为了满足当前能够允许多个独处,但只允许一个写入的需求,线程提供读写锁来实现。线程读取锁允许多个线程执行读出操作,而只允许一个线程执行写入操作,同时,读写操作是互斥的。
使用读写锁的基本操作如下:
初始化读写锁 pthread_rwlock_init
读取读写锁中的锁 pthread_rwlock_rdlock
读取非阻塞读写锁中的锁 pthread_rwlock_tryrdlock
写入读写锁中的锁 pthread_rwlock_wrlock
写入非阻塞读写锁中的锁 pthread_rwlock_trywrlock
解除锁定读写锁 pthread_rwlock_unlock
销毁读写锁 pthread_rwlock_destroy
1、读写锁应用实例
下面是一个使用读写锁来实现4个线程读写一段数据的实例。在此实例程序中,共创建了4个新的线程,其中两个线程用来读数据,两个线程用来写入数据。从运行结果看出,在任意时刻,如果有一个线程写数据,将阻塞所有其他线程任何操作,但在任意时刻有一个线程读数据,其他线程依然可以获得读数据锁,即可以执行读操作。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
#include <errno.h>
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <bits/pthreadtypes.h> static pthread_rwlock_t rwlock; //读写锁对象 #define WORK_SIZE 1024 char work_area[WORK_SIZE]; int time_to_exit; void *thread_function_read_o( void *arg); //读线程1 void *thread_function_read_t( void *arg); //读线程2 void *thread_function_write_o( void *arg); //写线程1 void *thread_function_write_t( void *arg); //写线程2 int main( int argc, char *argv[]) { int res; pthread_t a_thread, b_thread, c_thread, d_thread; void *thread_result; res = pthread_rwlock_init(&rwlock, NULL); //初始化读写锁 if (res != 0) { perror( "rwlock initialization failed"); exit(EXIT_FAILURE); } res = pthread_create(&a_thread, NULL, thread_function_read_o, NULL); //create new thread创建线程 if (res != 0) { perror( "Thread creation failed"); exit(EXIT_FAILURE); } res = pthread_create(&b_thread, NULL, thread_function_read_t, NULL); //create new thread if (res != 0) { perror( "Thread creation failed"); exit(EXIT_FAILURE); } res = pthread_create(&c_thread, NULL, thread_function_write_o, NULL); //create new thread if (res != 0) { perror( "Thread creation failed"); exit(EXIT_FAILURE); } res = pthread_create(&d_thread, NULL, thread_function_write_t, NULL); //create new thread if (res != 0) { perror( "Thread creation failed"); exit(EXIT_FAILURE); } res = pthread_join(a_thread, &thread_result); //等待a_thread线程结束 if (res != 0) { perror( "Thread join failed"); exit(EXIT_FAILURE); } res = pthread_join(b_thread, &thread_result); if (res != 0) { perror( "Thread join failed"); exit(EXIT_FAILURE); } res = pthread_join(c_thread, &thread_result); if (res != 0) { perror( "Thread join failed"); exit(EXIT_FAILURE); } res = pthread_join(d_thread, &thread_result); if (res != 0) { perror( "Thread join failed"); exit(EXIT_FAILURE); } pthread_rwlock_destroy(&rwlock); //销毁读写锁 exit(EXIT_SUCCESS); } void *thread_function_read_o( void *arg) //读线程1 { printf( "thread read one try to get lock\n"); pthread_rwlock_rdlock(&rwlock); //获取读取锁 while(strncmp( "end", work_area, 3) != 0) //非 end { printf( "this is thread read one."); printf( "the characters is %s", work_area); pthread_rwlock_unlock(&rwlock); sleep( 2); pthread_rwlock_rdlock(&rwlock); while (work_area[ 0] == '\0' ) //循环获取数据 { pthread_rwlock_unlock(&rwlock); sleep( 2); pthread_rwlock_rdlock(&rwlock); } } pthread_rwlock_unlock(&rwlock); time_to_exit = 1; pthread_exit( 0); } void *thread_function_read_t( void *arg) //读取锁2 { printf( "thread read one try to get lock\n"); pthread_rwlock_rdlock(&rwlock); while(strncmp( "end", work_area, 3) != 0) { printf( "this is thread read two."); printf( "the characters is %s", work_area); pthread_rwlock_unlock(&rwlock); sleep( 5); pthread_rwlock_rdlock(&rwlock); while (work_area[ 0] == '\0' ) { pthread_rwlock_unlock(&rwlock); sleep( 5); pthread_rwlock_rdlock(&rwlock); } } pthread_rwlock_unlock(&rwlock); time_to_exit = 1; pthread_exit( 0); } void *thread_function_write_o( void *arg) //写线程1 { printf( "this is write thread one try to get lock\n"); while(!time_to_exit) { pthread_rwlock_wrlock(&rwlock); printf( "this is write thread one.\nInput some text. Enter 'end' to finish\n"); fgets(work_area, WORK_SIZE, stdin); pthread_rwlock_unlock(&rwlock); sleep( 15); } pthread_rwlock_unlock(&rwlock); pthread_exit( 0); } void *thread_function_write_t( void *arg) //写线程2 { sleep( 10); while(!time_to_exit) { pthread_rwlock_wrlock(&rwlock); //获取写入锁 printf( "this is write thread two.\nInput some text. Enter 'end' to finish\n"); fgets(work_area, WORK_SIZE, stdin); //写入 pthread_rwlock_unlock(&rwlock); //解锁 sleep( 20); } pthread_rwlock_unlock(&rwlock); //解锁 pthread_exit( 0); } |