• 读写锁三种关系的证明(读者和读者互补影响、写者和写者互斥、读者和写者互斥)


            目录

    1、读者和读者互不影响

    2、写者和写者互斥

    3、读者和写者互斥

    (1) 读者持有锁

    (2) 写者持有锁


    1、读者和读者互不影响

    假设现在只有读者线程,我们让一个读者线程申请锁以后,但是不释放读写锁

    1. #include
    2. #include
    3. #include
    4. pthread_rwlock_t rwlock;
    5. void* read_thread(void* args){
    6. pthread_detach(pthread_self());
    7. int num = *(int*)args;
    8. while (1)
    9. {
    10. pthread_rwlock_rdlock(&rwlock); // 申请读者锁
    11. printf("读者[%d]正在读内容\n", num);
    12. sleep(1);
    13. //pthread_rwlock_unlock(&rwlock);
    14. }
    15. }
    16. int main(){
    17. pthread_t tid1,tid2,tid3,tid4;
    18. pthread_rwlock_init(&rwlock, NULL);
    19. int i = 1, j = 2;
    20. pthread_create(&tid1,NULL,read_thread, (void*)&i);
    21. pthread_create(&tid2,NULL,read_thread,(void*)&j);
    22. while(1){
    23. sleep(1);
    24. }
    25. return 0;
    26. }

    我们发现,读者和读者之间不会去争抢锁,即便是某一个读者线程申请到锁,也不会影响其他读者线程来申请锁。

     

    2、写者和写者互斥

    我们采用和上面类似的做法,只有两个写者线程,其中一个写者线程获取到锁以后,不释放锁,看一下另一个写者线程能否得到锁。

    1. #include
    2. #include
    3. #include
    4. pthread_rwlock_t rwlock;
    5. void* write_thread(void* args){
    6. pthread_detach(pthread_self());
    7. int num = *(int*)args;
    8. while (1)
    9. {
    10. pthread_rwlock_wrlock(&rwlock);
    11. printf("写者[%d]正在写内容\n", num);
    12. //pthread_rwlock_unlock(&rwlock);
    13. sleep(1);
    14. }
    15. }
    16. int main(){
    17. pthread_t tid1,tid2,tid3,tid4;
    18. pthread_rwlock_init(&rwlock, NULL);
    19. int i = 1, j = 2;
    20. pthread_create(&tid3,NULL,write_thread,(void*)&i);
    21. pthread_create(&tid4,NULL,write_thread,(void*)&j);
    22. while(1){
    23. sleep(1);
    24. }
    25. return 0;
    26. }

    我们发现始终只有写者2在打印,说明写者2拿到锁以后,写者1就无法获取到锁了。说明写者和写者之间是互斥的。

     

    3、读者和写者互斥

    这里就分为两种场景:读者持有锁、写者持有锁。

    • 读者持有锁时,写者申请锁会阻塞等待,但是读者申请锁不受影响。
    • 写者持有锁时,无论是读锁申请还是写锁申请,都会被阻塞

    (1) 读者持有锁

    现在有三个线程,两个读线程,一个写线程,他们执行的操作如下:

    • 读者[1]:立马申请锁,但是不释放
    • 写者[1]:延迟1s以后申请(验证写者申请锁是否会被阻塞)
    • 读者[2]:延迟2s后申请(验证写者之后的读锁申请是否会被阻塞)
    1. #include
    2. #include
    3. #include
    4. pthread_rwlock_t rwlock;
    5. void* read_thread1(void* args){
    6. pthread_detach(pthread_self());
    7. printf("读者[1]申请锁\n");
    8. while (1)
    9. {
    10. pthread_rwlock_rdlock(&rwlock);
    11. printf("读者[1]正在读内容\n");
    12. sleep(1);
    13. // pthread_rwlock_unlock(&rwlock); // 读者1不释放锁
    14. }
    15. }
    16. void* read_thread2(void* args){
    17. pthread_detach(pthread_self());
    18. //int num = *(int*)args;
    19. sleep(2); // 让读者[2]延迟2s再申请
    20. printf("读者[2]申请锁\n");
    21. while (1)
    22. {
    23. pthread_rwlock_rdlock(&rwlock);
    24. printf("读者[2]正在读内容\n");
    25. pthread_rwlock_unlock(&rwlock);
    26. sleep(1);
    27. }
    28. }
    29. void* write_thread(void* args){
    30. pthread_detach(pthread_self());
    31. sleep(1); // 让写者[1]延迟1s再申请
    32. printf("写者1申请锁\n");
    33. while (1)
    34. {
    35. pthread_rwlock_wrlock(&rwlock);
    36. printf("写者[1]正在写内容\n");
    37. pthread_rwlock_unlock(&rwlock);
    38. sleep(1);
    39. }
    40. }
    41. int main(){
    42. pthread_t tid1,tid2,tid3,tid4;
    43. pthread_rwlock_init(&rwlock, NULL);
    44. int i = 1, j = 2;
    45. pthread_create(&tid1,NULL,read_thread1, NULL);
    46. pthread_create(&tid2,NULL,read_thread2, NULL);
    47. pthread_create(&tid3,NULL,write_thread, NULL);
    48. while(1){
    49. sleep(1);
    50. }
    51. return 0;
    52. }

    (2) 写者持有锁

    我们采用和上面类似的步骤,

    • 写者[1]:先申请锁,但不释放
    • 其他读者:延迟1s后申请
    1. #include
    2. #include
    3. #include
    4. pthread_rwlock_t rwlock;
    5. void* read_thread1(void* args){
    6. pthread_detach(pthread_self());
    7. sleep(1); // 让读者[1]延迟1s再申请
    8. printf("读者[1]申请锁\n");
    9. while (1)
    10. {
    11. pthread_rwlock_rdlock(&rwlock);
    12. printf("读者[1]正在读内容\n");
    13. pthread_rwlock_unlock(&rwlock);
    14. sleep(1);
    15. }
    16. }
    17. void* read_thread2(void* args){
    18. pthread_detach(pthread_self());
    19. //int num = *(int*)args;
    20. sleep(1); // 让读者[2]延迟1s再申请
    21. printf("读者[2]申请锁\n");
    22. while (1)
    23. {
    24. pthread_rwlock_rdlock(&rwlock);
    25. printf("读者[2]正在读内容\n");
    26. pthread_rwlock_unlock(&rwlock);
    27. sleep(1);
    28. }
    29. }
    30. void* write_thread(void* args){
    31. pthread_detach(pthread_self());
    32. printf("写者1申请锁\n");
    33. while (1)
    34. {
    35. pthread_rwlock_wrlock(&rwlock);
    36. printf("写者[1]正在读内容\n");
    37. // pthread_rwlock_unlock(&rwlock); // 写者1不释放锁
    38. sleep(1);
    39. }
    40. }
    41. int main(){
    42. pthread_t tid1,tid2,tid3,tid4;
    43. pthread_rwlock_init(&rwlock, NULL);
    44. int i = 1, j = 2;
    45. pthread_create(&tid1,NULL,read_thread1, NULL);
    46. pthread_create(&tid2,NULL,read_thread2, NULL);
    47. pthread_create(&tid3,NULL,write_thread, NULL);
    48. while(1){
    49. sleep(1);
    50. }
    51. return 0;
    52. }

  • 相关阅读:
    Mysql: COMMIT 和 ROLLBACK
    [树上倍增]Eezie and Pie 2022牛客多校第6场 B
    Linux网络命令使用简单说明
    RSTP与MSTP
    30分钟带你精通git使用
    经典供货保密协议模板
    房产网小程序源码 房产中介小程序源码 房产网源码
    一文了解“字符集”
    【已解决】VS2008下MFC程序如何设置多语言
    low power-upf-vcsnlp(二)
  • 原文地址:https://blog.csdn.net/challenglistic/article/details/128161178