当前位置:   article > 正文

educoder : Linux之线程同步二(3)_linux之线程同步二头歌答案

linux之线程同步二头歌答案

第3关:项目实战

任务描述

本关任务:利用信号量实现一个读写锁。

相关知识

Linux 系统中提供了现成的读写锁库函数,也就是上一关我们学习的。其实,我们利用其他线程同步的方法也可以实现一个读写锁

读写锁 需要满足如下规则:

  1. 如果某线程申请了读锁,其它线程可以再申请读锁,但不能申请写锁;
  2. 如果某线程申请了写锁,其它线程不能申请读锁,也不能申请写锁;

通过实训"Linux之线程同步一"的学习,我们现在知道如何互斥锁和条件变量来同步线程。那么利用 互斥锁条件变量 知识就可以简单的读写锁。

利用条件变量和互斥锁实现读写锁

使用条件变量和互斥锁实现读写锁,根据读写锁的特性,当有读者在读取数据时,则不能有线程对数据进行写操作,并且同时可以存在多个读者。当有写者在对数据进行写操作的时候,则不能有线程对数据进行读操作,并且同一时刻只能有一个写者。因此,实现一个简单的读写锁可以分为以下几步:

  1. 1. 定义两个变量用于记录读者(readNum)和写者(writeNum)的个数;
  2. 2. 对于写模式的加锁,如果readNum和writeNum同时为0,则将writeNum设置为1表示此时有一个写者需要对数据进行写操作;否则,写模式的加锁操作处于等待状态;
  3. 3. 对于写模式的解锁,如果完成的写操作,此时需要将writeNum设置为0,表示此时没有写操作,并且通知读者可以读取数据了;
  4. 4. 对于读模式的加锁,如果writeNum为0,则表示当前没有写操作,可以读取数据,并且将readNum值加一表示多了一个读者;否则,读模式的加锁操作处于等待状态;
  5. 5. 对于读模式的解锁,如果完成的读操作,此时需要将readNum减一操作,然后判断readNum是否为0,如果为零,则通知写者可以执行写操作;

利用互斥锁实现读写锁

只使用互斥锁也可以实现读写锁,详细的步骤可分为以下几步:

  1. 1. 定义一个变量用于记录读者(readNum)的个数和两个互斥锁,分别是读模式的互斥锁(mutex_read)和写模式的互斥锁(mutex_write);
  2. 2. 对于写模式的加锁,直接对mutex_write进行加锁操作即可;
  3. 3. 对于写模式的解锁,直接对mutex_write进行解锁操作即可;
  4. 4. 对于读模式的加锁,首先判断读者的数量是否为0,如果为0,则表示第一个读者要去读取数据,那么此时要禁止写者进行写数据操作,所以对mutex_write进行加锁操作并设置readNum++;否则直接将readNum++即可;
  5. 5. 对于读模式的解锁,首先将readNum--,然后判断此时是否readNum为0,如果为0,则表示现在允许写者可以写数据,因此要对mutex_write进行解锁操作;

编程要求

本关的编程任务是补全右侧代码片段中BeginEnd中间的代码,具体要求如下:

  • 利用信号量实现读写锁功能;
  • 补全sem_rwlock_rdlocksem_rwlock_unrdlock函数;
  • sem_rwlock_rdlock函数用于读模式下的读加锁操作;
  • sem_rwlock_unrdlock函数用于读模式下的读解锁操作;
  • 提示:参考两个互斥锁和一个变量实现读写锁的方式,互斥锁其实就是 0-1 信号量;
  • 评测读写锁实现是否正确所使用的测试用例与上一关测试用例一致,详细描述参考上一关编程要求介绍;
  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <semaphore.h>
  4. //记录读线程的个数
  5. extern int reader;
  6. //全局的信号量变量
  7. extern sem_t sem_read, sem_write;
  8. //读写锁初始化函数
  9. void sem_rwlock_init()
  10. {
  11. reader = 0;
  12. //初始化信号量个1
  13. sem_init(&sem_read, 0, 1);
  14. sem_init(&sem_write, 0, 1);
  15. }
  16. //读写锁注销函数
  17. void sem_rwlock_destroy()
  18. {
  19. sem_destroy(&sem_read);
  20. sem_destroy(&sem_write);
  21. }
  22. //读模式下的加锁操作
  23. void sem_rwlock_rdlock()
  24. {
  25. //读模式下加锁操作
  26. /********** BEGIN **********/
  27. sem_wait(&sem_read);
  28. if(reader == 0)
  29. sem_wait(&sem_write);
  30. reader++;
  31. sem_post(&sem_read);
  32. /********** END **********/
  33. }
  34. //读模式下的解锁操作
  35. void sem_rwlock_unrdlock()
  36. {
  37. //读模式下解锁操作
  38. /********** BEGIN **********/
  39. sem_wait(&sem_read);
  40. reader--;
  41. if(reader == 0)
  42. sem_post(&sem_write);
  43. sem_post(&sem_read);
  44. /********** END **********/
  45. }
  46. //写模式下的加锁操作
  47. void sem_rwlock_wrlock()
  48. {
  49. sem_wait(&sem_write);
  50. }
  51. //写模式下的解锁操作
  52. void sem_rwlock_unwrlock()
  53. {
  54. sem_post(&sem_write);
  55. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/336615
推荐阅读
相关标签
  

闽ICP备14008679号