Linux线程之读写锁小结

打印 上一主题 下一主题

主题 904|帖子 904|积分 2712

读写锁(rwlock)与互斥锁(Mutex Lock)相比,有如下特点:

  • 更加细致的区分了读和写,给共享资源分别上了“读”锁和“写”锁。
  • “写”独占,“读”共享,“写”锁优先级更高
  • 如果共享资源在绝大多数情况下是“读”操作,可以提高步伐的并发性能。
常用的函数原型总结如下:
  1. pthread_rwlock_t rwlock (= PTHREAD_RWLOCK_INITIALIZER); // 定义读写锁的变量并初始化,一定要全局变量,如果使用了下述初始化函数,括号内静态初始化就可以取消
  2. pthread_rwlock_init(&rwlock, NULL);                       // const pthread_rwlockattr_t *restrict attr,第二个参数默认为NULL
  3. pthread_rwlock_rdlock(&rwlock);                           // 上读锁,并进行读操作
  4. pthread_rwlock_wrlock(&rwlock);                           // 上写锁,并进行写操作,同一时间只有一把写锁,并与其他锁互斥
  5. pthread_rwlock_unlock(&rwlock);                           // 解锁,读和写的解锁函数都相同
  6. pthread_rwlock_destroy(&rwlock);                          // 不用了就销毁读写锁
复制代码
设计一个步伐,步伐中有3个线程,主线程A创建一个文本,每隔5s获取一次系统时间并写入到该文本中,另外两个线程B和C分别从文本中读取当前的时间和日期,子线程B输出系统时间"hh:mm:ss",子线程c输出系统日期"2024年05月31日”,要求使用读写锁实现互斥。 提示:主线程A获取写操作的锁,另外的线程分别获取读操作的锁,步伐如下:
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <pthread.h>
  4. #include <time.h>
  5. FILE *timefp;            // 以文件句柄为共享区
  6. pthread_rwlock_t rwlock; // 定义读写锁的变量,一定要全局变量
  7. // 需要用到的时间结构体,提前列出
  8. //  struct tm {
  9. //                 int tm_sec;    /* Seconds (0-60) */
  10. //  int tm_min;   /* Minutes (0-59) */
  11. //  int tm_hour;  /* Hours (0-23) */
  12. //  int tm_mday;  /* Day of the month (1-31) */
  13. //  int tm_mon;   /* Month (0-11) */
  14. //  int tm_year;  /* Year - 1900 */
  15. //  int tm_wday;  /* Day of the week (0-6, Sunday = 0) */
  16. //  int tm_yday;  /* Day in the year (0-365, 1 Jan = 0) */
  17. //  int tm_isdst; /* Daylight saving time */
  18. //  }
  19. void *funcB(void *arg) // B线程
  20. {
  21.     time_t tlocB = 0;
  22.     while (1)
  23.     {
  24.         pthread_rwlock_rdlock(&rwlock); // 上锁,进行读操作
  25.         timefp = fopen("/home/rice/0531/time.txt", "r+");
  26.         fread(&tlocB, sizeof(time_t), 1, timefp);
  27.         struct tm *tt = localtime(&tlocB);
  28.         printf("I am thread B,the time is ===== %02d:%02d:%02d\n", tt->tm_hour, tt->tm_min, tt->tm_sec);
  29.         pthread_rwlock_unlock(&rwlock); // 解锁,释放权限
  30.         fclose(timefp);
  31.         sleep(2); // 每隔两秒进行一次输出
  32.     }
  33. }
  34. void *funcC(void *arg)
  35. {
  36.     time_t tlocC = 0;
  37.     while (1)
  38.     {
  39.         pthread_rwlock_rdlock(&rwlock); // 上锁,进行读操作
  40.         timefp = fopen("/home/rice/0531/time.txt", "rb+");
  41.         fread(&tlocC, sizeof(time_t), 1, timefp);
  42.         struct tm *tt = localtime(&tlocC);
  43.         printf("I am thread C,the date is ===== %d年:%02d月:%02d日\n", tt->tm_year + 1900, tt->tm_mon + 1, tt->tm_mday);
  44.         pthread_rwlock_unlock(&rwlock); // 解锁,释放权限
  45.         fclose(timefp);
  46.         sleep(2); // 每隔两秒进行一次输出
  47.     }
  48. }
  49. int main()
  50. {
  51.     pthread_rwlock_init(&rwlock, NULL); // 初始化读写锁
  52.     pthread_t tidB, tidC;
  53.     pthread_create(&tidB, NULL, funcB, NULL); // 创建线程
  54.     pthread_create(&tidC, NULL, funcC, NULL);
  55.     while (1) // 主线程每隔5秒获取一次系统时间
  56.     {
  57.         pthread_rwlock_wrlock(&rwlock); // 上锁,进行写操作
  58.         timefp = fopen("/home/rice/0531/time.txt", "wb+"); // 打开文件,不存在就创建
  59.         time_t tloc = time(NULL);
  60.         fwrite(&tloc, sizeof(time_t), 1, timefp); // 将time原始数据存入文件
  61.         fclose(timefp);
  62.         pthread_rwlock_unlock(&rwlock); // 解锁,释放文件权限
  63.         sleep(5);                       // 每隔5秒进行一次写入操作
  64.     }
  65.     // 等待B和C线程结束
  66.     pthread_join(tidB, NULL);
  67.     pthread_join(tidC, NULL);
  68.     // 销毁读写锁
  69.     pthread_rwlock_destroy(&rwlock);
  70.     return 0;
  71. }
复制代码
输出结果如下:
  1. I am thread B,the time is ===== 20:10:57
  2. I am thread C,the date is ===== 2024年:06月:01日
  3. I am thread B,the time is ===== 20:10:57
  4. I am thread C,the date is ===== 2024年:06月:01日
  5. I am thread C,the date is ===== 2024年:06月:01日
  6. I am thread B,the time is ===== 20:10:57
  7. I am thread B,the time is ===== 20:11:02
  8. I am thread C,the date is ===== 2024年:06月:01日
  9. I am thread B,the time is ===== 20:11:02
  10. I am thread C,the date is ===== 2024年:06月:01日
  11. ...
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美食家大橙子

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表