Chinaunix首页 | 论坛 | 博客
  • 博客访问: 22779
  • 博文数量: 19
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 15
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-29 19:57
文章分类
文章存档

2014年(13)

2013年(6)

我的朋友

分类: LINUX

2013-04-29 20:20:39

原文地址:linux下使用读写锁 作者:yuyunliuhen

    在多线程程序中,有一种读写者的问题,即对某些资源的访问,存在两种可能的情况,一种是访问必须排他的,称为写操作;另外一种访问是可共享的,称为读操作。
    处理读写着问题的两种常见策略是:强读者同步和强写者同步。在强读者同步过程中,总是给读者优先权,只要写着当前没有进行写操作,读者就可以获得访问权。在强写者同步过程中,通常将优先权先交给写者,而将读者延迟到所有等待的或者活动的写者都完成为止。简单的说:
    (1)可以同时存在多个读操作
    (2)写必须互斥(只允许一个写操作,不能读写操作同时进行)
    (3)写操作优先于读操作,(一旦有写操作,后续的读操作必须等待,唤醒时有限考虑写操作)
    下面是两种读写锁的使用示例.
    一:POSIX 下的rw_lock

点击(此处)折叠或打开

  1. #include <pthread.h>
  2. #include <cstdlib>
  3. #include <ctime>
  4. #include <iostream>
  5. using namespace std;

  6. static int count = 0;
  7. class Test
  8. {
  9. private :
  10.     pthread_rwlock_t rwlock;
  11.     
  12.     static void* shared_task_handler(void* arg)
  13.     {
  14.         Test* testptr = static_cast<Test*>(arg);
  15.         pthread_rwlock_rdlock(&testptr->rwlock);
  16.         //    do the shared task here
  17.         cout << "read---count = " << count << endl;
  18.         if (pthread_rwlock_unlock(&testptr->rwlock) )
  19.         {
  20.             cout << "read unlock error " << endl;
  21.         }
  22.         return NULL;
  23.     }
  24.     
  25.     static void * exclusive_task_handler(void * arg)
  26.     {
  27.         Test* testptr = static_cast<Test*>(arg);
  28.         pthread_rwlock_wrlock(&testptr->rwlock);
  29.         //do the exclusive task here
  30.         ++count;
  31.         cout << "write--count = " << count << endl;
  32.         if (pthread_rwlock_unlock(&testptr->rwlock) )
  33.         {
  34.             cout << "write unlock error " << endl;
  35.         }
  36.         return NULL;
  37.     }
  38.     
  39. public :
  40.     typedef void* (*ThreadFunc) (void*);
  41.     void start()
  42.     {
  43.         srand(time(NULL));
  44.         
  45.         if( pthread_rwlock_init(&rwlock,NULL) )
  46.         {
  47.             cout << "rwlock init error " << endl;
  48.         }

  49.         const int THREADS_NO = rand()%100;
  50.         pthread_t* threads = new pthread_t[THREADS_NO];

  51.         for(int i = 0; i < THREADS_NO; ++i)
  52.         {
  53.             ThreadFunc tmpfunc = rand() % 2 ? shared_task_handler : exclusive_task_handler;
  54.             if (pthread_create(threads+i,NULL,tmpfunc,this))
  55.             {
  56.                 cerr << "pthread_create fails" << endl;
  57.                 exit(1);
  58.             }
  59.         }
  60.         rwlock
  61.         for(int i=0; i<THREADS_NO; i++)
  62.         {
  63.             pthread_join(threads[i],NULL);
  64.         }
  65.         delete[] threads;
  66.     }
  67. };

  68. int main()
  69. {
  70.     Test tmptest;
  71.     tmptest.start();
  72. }

output:

点击(此处)折叠或打开

  1. lee@lee-desktop:~/share$ ./posix_read_write_lock
  2. write--count = 1
  3. write--count = 2
  4. write--count = 3
  5. read---count = 3
  6. read---count = 3
  7. read---count = 3
  8. read---count = 3
  9. write--count = 4
  10. read---count = 4
  11. write--count = 5
  12. write--count = 6
  13. read---count = 6
  14. read---count = 6
  15. read---count = 6
  16. read---count = 6
  17. write--count = 7
  18. write--count = 8
  19. read---count = 8
  20. read---count = 8
  21. write--count = 9
  22. write--count = 10
  23. read---count = 10
  24. read---count = 10
  25. read---count = 10
  26. read---count = 10
  27. read---count = 10
  28. read---count = 10
  29. read---count = 10
  30. write--count = 11
  31. write--count = 12
  32. write--count = 13
  33. write--count = 14
  34. write--count = 15
  35. read---count = 15

    二:利用pthread_cond_*  &  pthread_mutex_* 实现rw_lock

 

点击(此处)折叠或打开

  1. #include <pthread.h>
  2. #include <cstdlib>
  3. #include <ctime>
  4. #include <iostream>
  5. using namespace std;

  6. class RWLock
  7. {
  8. private :
  9.     pthread_mutex_t cnt_mutex;
  10.     pthread_cond_t rw_cond;
  11.     int rd_cnt, wr_cnt;

  12.     RWLock(const RWLock&);
  13.     RWLock& operator= (const RWLock&);

  14. public :
  15.     RWLock(): rd_cnt(0),wr_cnt(0)
  16.     {
  17.         pthread_mutex_init(&cnt_mutex, NULL);
  18.         pthread_cond_init(&rw_cond, NULL);
  19.     }

  20.     void get_shared_lock()
  21.     {
  22.         pthread_mutex_lock(&cnt_mutex);
  23.         while (wr_cnt >0)
  24.         {
  25.             pthread_cond_wait(&rw_cond,&cnt_mutex);
  26.         }
  27.         rd_cnt++;
  28.         pthread_mutex_unlock(&cnt_mutex);
  29.     }

  30.     void release_shared_lock()
  31.     {
  32.         pthread_mutex_lock(&cnt_mutex);
  33.         rd_cnt--;
  34.         if (0 == rd_cnt)
  35.         {
  36.             pthread_cond_signal(&rw_cond);
  37.         }
  38.         pthread_mutex_unlock(&cnt_mutex);
  39.     }

  40.     void get_exclusive_lock()
  41.     {
  42.         pthread_mutex_lock(&cnt_mutex);
  43.         while (rd_cnt + wr_cnt>0)
  44.         {
  45.             pthread_cond_wait(&rw_cond,&cnt_mutex);
  46.         }
  47.         wr_cnt++;
  48.         pthread_mutex_unlock(&cnt_mutex);
  49.     }

  50.     void release_exclusive_lock()
  51.     {
  52.         pthread_mutex_lock(&cnt_mutex);
  53.         wr_cnt--;
  54.         pthread_cond_broadcast(&rw_cond);
  55.         pthread_mutex_unlock(&cnt_mutex);
  56.     }

  57.     ~RWLock()
  58.     {
  59.         pthread_mutex_destroy(&cnt_mutex);
  60.         pthread_cond_destroy(&rw_cond);
  61.     }
  62. };

  63. static int count = 0;
  64. class Test
  65. {
  66. private :
  67.     RWLock lock;
  68.     
  69.     static void* shared_task_handler(void* arg)
  70.     {
  71.         Test* testptr = static_cast<Test*>(arg);
  72.         testptr->lock.get_shared_lock();
  73.         //    do the shared task here
  74.         cout << "read---count = " << count << endl;
  75.         testptr->lock.release_shared_lock();
  76.     }
  77.     
  78.     static void * exclusive_task_handler(void * arg)
  79.     {
  80.         Test* testptr = static_cast<Test*>(arg);
  81.         testptr->lock.get_exclusive_lock();
  82.         //do the exclusive task here
  83.         ++count;
  84.         cout << "write--count = " << count << endl;
  85.         testptr->lock.release_exclusive_lock();
  86.     }
  87.     
  88. public :
  89.     typedef void* (*ThreadFunc) (void*);
  90.     void start()
  91.     {
  92.         srand(time(NULL));

  93.         const int THREADS_NO = rand()%100;
  94.         pthread_t* threads = new pthread_t[THREADS_NO];

  95.         for(int i = 0; i < THREADS_NO; ++i)
  96.         {
  97.             ThreadFunc tmpfunc = rand() % 2 ? shared_task_handler : exclusive_task_handler;
  98.             if (pthread_create(threads+i,NULL,tmpfunc,this))
  99.             {
  100.                 cerr << "pthread_create fails" << endl;
  101.                 exit(1);
  102.             }
  103.         }

  104.         for(int i=0; i<THREADS_NO; i++)
  105.         {
  106.             pthread_join(threads[i],NULL);
  107.         }

  108.         delete[] threads;
  109.     }
  110. };

  111. int main()
  112. {
  113.     Test tmptest;
  114.     tmptest.start();
  115. }

  output:

点击(此处)折叠或打开

  1. lee@lee-desktop:~/share$ ./read_write_lock
  2. read---count = 0
  3. read---count = 0
  4. read---count = 0
  5. write--count = 1
  6. read---count = 1
  7. read---count = 1
  8. read---count = 1
  9. read---count = 1
  10. write--count = 2
  11. write--count = 3
  12. read---count = 3
  13. read---count = 3
  14. read---count = 3
  15. read---count = 3
  16. read---count = 3
  17. read---count = 3
  18. read---count = 3
  19. read---count = 3
  20. read---count = 3
  21. read---count = 3
  22. read---count = 3
  23. read---count = 3
  24. read---count = 3
  25. write--count = 4
  26. write--count = 5
  27. write--count = 6
  28. write--count = 7
  29. write--count = 8
  30. write--count = 9
  31. write--count = 10
  32. write--count = 11
  33. read---count = 11
  34. write--count = 12
  35. write--count = 13
  36. read---count = 13
  37. read---count = 13
  38. write--count = 14
  39. write--count = 15
  40. write--count = 16
  41. write--count = 17
  42. write--count = 18
  43. write--count = 19
  44. read---count = 19
  45. write--count = 20
  46. read---count = 20
  47. write--count = 21
  48. read---count = 21
  49. write--count = 22
  50. read---count = 22
  51. read---count = 22
  52. write--count = 23
  53. read---count = 23
  54. read---count = 23
  55. read---count = 23
  56. write--count = 24
  57. read---count = 24
  58. write--count = 25
  59. write--count = 26
  60. write--count = 27
  61. write--count = 28
  62. read---count = 28
  63. read---count = 28
  64. write--count = 29
  65. write--count = 30
  66. read---count = 30
  67. read---count = 30
  68. read---count = 30
  69. write--count = 31
  70. read---count = 31
  71. read---count = 31
  72. write--count = 32
  73. read---count = 32
  74. write--count = 33
  75. read---count = 33
  76. read---count = 33
  77. read---count = 33
  78. read---count = 33
  79. read---count = 33
  80. write--count = 34
  81. write--count = 35

    参考:
        http://www.cppblog.com/bigsml/archive/2006/09/07/12137.html
 
阅读(181) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~