读写锁
对于互斥锁而言,凡是涉及临界资源的访问一律加锁,这在并发读操作的场景下会大量浪费时间。要想提高访问效率,就必须要将对资源的读写操作加以区分:读操作可以多任务并发执行,只有写操作才进行恰当的互斥。Linux系统就提供了一种读写锁。
(1)读写锁的初始化- pthread_rwlock_t rwlock (= PTHREAD_RWLOCK_INITIALIZER); // 定义读写锁的变量并初始化,一定要全局变量,如果使用了下述初始化函数,括号内静态初始化就可以取消
- pthread_rwlock_init(&rwlock, NULL); // const pthread_rwlockattr_t *restrict attr,第二个参数默认为NULL
复制代码 (2)读写锁的上锁和解锁- pthread_rwlock_rdlock(&rwlock); // 上读锁,并进行读操作
- pthread_rwlock_wrlock(&rwlock); // 上写锁,并进行写操作,同一时间只有一把写锁,并与其他锁互斥
- pthread_rwlock_unlock(&rwlock); // 解锁,读和写的解锁函数都相同
- pthread_rwlock_destroy(&rwlock); // 不用了就销毁读写锁
复制代码 注意:读写锁适合多个线程对共享资源进行读操作和写操作,并且写操作没有读操作频繁的情况,另外要注意,如果多条线程对资源进行读取时,可以添加多把读操作锁。如果有一条线程准备对资源进行修改,则不应该有其他的线程再对资源进行读或者写,就相当于写操作和读操作是互斥的。如果已经有一条线程获取了写操作锁,那其他线程就无法获取写操作锁,就需要进行阻塞等待,所以就相当与写操作和写操作是互斥的。
(3)练习
设计一个程序,程序中有3个线程,主线程A创建一个文本,每隔5s获取一次系统时间并写入到该文本中,另外两个线程B和C分别从文本中读取当前的时间和日期,子线程B输出系统时间”hh:mm:ss”,子线程C输出系统日期”2024年05月31日”,要求使用读写锁实现互斥。 提示:主线程A获取写操作的锁,另外的线程分别获取读操作的锁。- #include <errno.h>
- #include <stdio.h>
- #include <pthread.h>
- #include <time.h>
- //定义全局变量
- pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
- FILE *time_fd;
- //进程B
- void * task_B(void *task_B)
- {
- char buf[128]={0};
- //设置分离属性
- pthread_detach(pthread_self());
- while(1)
- {
- //1.读锁
- pthread_rwlock_rdlock(&rwlock);
- //2.读取时间
- time_fd = fopen("./time.txt", "r+");//打开文件
- fread(buf,strlen(time_fd),1,time_fd);
- printf("I am pthread B,time:%s", ctime(buf));
- fclose(time_fd);
- //3.解锁
- pthread_rwlock_unlock(&rwlock);
- sleep(2);
- }
-
- }
- //进程C
- void * task_C(void *task_B)
- {
- char buf[128]={0};
- //设置分离属性
- pthread_detach(pthread_self());
- while(1)
- {
- //1.读锁
- pthread_rwlock_rdlock(&rwlock);
- //2.读取时间
- time_fd = fopen("./time.txt", "r+");//打开文件
- fread(buf,strlen(time_fd),1,time_fd);
- struct tm *p;
- p = localtime(buf);
- printf("%d年,%d月,%d日\r\n", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
- fclose(time_fd);
- //3.解锁
- pthread_rwlock_unlock(&rwlock);
- sleep(2);
- }
-
- }
- int main()
- {
- //1.初始化读写锁
- pthread_rwlock_init(&rwlock,NULL);
- //2.创建两个线程:线程B、线程C
- pthread_t thread_C;
- pthread_t thread_B;
- pthread_create(thread_C,NULL,task_C,NULL);
- pthread_create(thread_B,NULL,task_B,NULL);
- //3.打开一个文本,如果不存在就创建
- time_fd=fopen("./time.txt","wb+");
- if(time_fd=NULL)
- {
- fprintf(stderr,"open time_log error,errno=%d,%s\n",errno,strerror(errno));
- exit(-1);
- }
- //4.循环向time.txt文件中写入时间
- while(1)
- {
- //1.写上锁
- pthread_rwlock_wrlock(&rwlock);
- //2.向time.txt文件中写入系统时间
- time_t new;
- time (&new);
- fwrite(&new,sizeof(new),1,time_fd);
- //3.解锁
- pthread_rwlock_unlock(&rwlock);
- //4.睡眠
- sleep(5);
- }
- // 销毁读写锁
- pthread_rwlock_destroy(&rwlock);
- fclose(time_fd);
- return 0;
-
- }
复制代码 来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |