找回密码
 立即注册
首页 业界区 安全 读写锁

读写锁

瞧厨 2025-6-11 15:28:07
读写锁

对于互斥锁而言,凡是涉及临界资源的访问一律加锁,这在并发读操作的场景下会大量浪费时间。要想提高访问效率,就必须要将对资源的读写操作加以区分:读操作可以多任务并发执行,只有写操作才进行恰当的互斥。Linux系统就提供了一种读写锁。
(1)读写锁的初始化
  1. pthread_rwlock_t rwlock (= PTHREAD_RWLOCK_INITIALIZER); // 定义读写锁的变量并初始化,一定要全局变量,如果使用了下述初始化函数,括号内静态初始化就可以取消
  2. pthread_rwlock_init(&rwlock, NULL);                       // const pthread_rwlockattr_t *restrict attr,第二个参数默认为NULL
复制代码
(2)读写锁的上锁和解锁
  1. pthread_rwlock_rdlock(&rwlock);                           // 上读锁,并进行读操作
  2. pthread_rwlock_wrlock(&rwlock);                           // 上写锁,并进行写操作,同一时间只有一把写锁,并与其他锁互斥
  3. pthread_rwlock_unlock(&rwlock);                           // 解锁,读和写的解锁函数都相同
  4. pthread_rwlock_destroy(&rwlock);                          // 不用了就销毁读写锁
复制代码
注意:读写锁适合多个线程对共享资源进行读操作和写操作,并且写操作没有读操作频繁的情况,另外要注意,如果多条线程对资源进行读取时,可以添加多把读操作锁。如果有一条线程准备对资源进行修改,则不应该有其他的线程再对资源进行读或者写,就相当于写操作和读操作是互斥的。如果已经有一条线程获取了写操作锁,那其他线程就无法获取写操作锁,就需要进行阻塞等待,所以就相当与写操作和写操作是互斥的。
(3)练习
设计一个程序,程序中有3个线程,主线程A创建一个文本,每隔5s获取一次系统时间并写入到该文本中,另外两个线程B和C分别从文本中读取当前的时间和日期,子线程B输出系统时间”hh:mm:ss”,子线程C输出系统日期”2024年05月31日”,要求使用读写锁实现互斥。 提示:主线程A获取写操作的锁,另外的线程分别获取读操作的锁。
  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <pthread.h>
  4. #include <time.h>
  5. //定义全局变量
  6. pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
  7. FILE *time_fd;
  8. //进程B
  9. void * task_B(void *task_B)
  10. {
  11.     char buf[128]={0};
  12.     //设置分离属性
  13.     pthread_detach(pthread_self());
  14.     while(1)
  15.     {
  16.         //1.读锁
  17.         pthread_rwlock_rdlock(&rwlock);
  18.         //2.读取时间
  19.         time_fd = fopen("./time.txt", "r+");//打开文件
  20.         fread(buf,strlen(time_fd),1,time_fd);
  21.         printf("I am pthread B,time:%s", ctime(buf));
  22.         fclose(time_fd);
  23.         //3.解锁
  24.         pthread_rwlock_unlock(&rwlock);
  25.         sleep(2);
  26.     }
  27.    
  28. }
  29. //进程C
  30. void * task_C(void *task_B)
  31. {
  32.     char buf[128]={0};
  33.     //设置分离属性
  34.     pthread_detach(pthread_self());
  35.     while(1)
  36.     {
  37.         //1.读锁
  38.         pthread_rwlock_rdlock(&rwlock);
  39.         //2.读取时间
  40.         time_fd = fopen("./time.txt", "r+");//打开文件
  41.         fread(buf,strlen(time_fd),1,time_fd);
  42.         struct tm *p;
  43.         p = localtime(buf);
  44.         printf("%d年,%d月,%d日\r\n", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
  45.         fclose(time_fd);
  46.         //3.解锁
  47.         pthread_rwlock_unlock(&rwlock);
  48.         sleep(2);
  49.     }
  50.    
  51. }
  52. int main()
  53. {
  54.     //1.初始化读写锁
  55.     pthread_rwlock_init(&rwlock,NULL);
  56.     //2.创建两个线程:线程B、线程C
  57.     pthread_t thread_C;
  58.     pthread_t thread_B;
  59.     pthread_create(thread_C,NULL,task_C,NULL);
  60.     pthread_create(thread_B,NULL,task_B,NULL);
  61.     //3.打开一个文本,如果不存在就创建
  62.     time_fd=fopen("./time.txt","wb+");
  63.     if(time_fd=NULL)
  64.     {
  65.         fprintf(stderr,"open time_log error,errno=%d,%s\n",errno,strerror(errno));
  66.         exit(-1);
  67.     }
  68.     //4.循环向time.txt文件中写入时间
  69.     while(1)
  70.     {
  71.         //1.写上锁
  72.         pthread_rwlock_wrlock(&rwlock);
  73.         //2.向time.txt文件中写入系统时间
  74.         time_t new;
  75.         time (&new);
  76.         fwrite(&new,sizeof(new),1,time_fd);
  77.         //3.解锁
  78.         pthread_rwlock_unlock(&rwlock);
  79.         //4.睡眠
  80.         sleep(5);
  81.     }
  82.     // 销毁读写锁
  83.     pthread_rwlock_destroy(&rwlock);
  84.     fclose(time_fd);
  85.     return 0;
  86.    
  87. }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册