linux下使用读写锁

简介:     在多线程程序中,有一种读写者的问题,即对某些资源的访问,存在两种可能的情况,一种是访问必须排他的,称为写操作;另外一种访问是可共享的,称为读操作。     处理读写着问题的两种常见策略是:强读者同步和强写者同步。
    在多线程程序中,有一种读写者的问题,即对某些资源的访问,存在两种可能的情况,一种是访问必须排他的,称为写操作;另外一种访问是可共享的,称为读操作。
    处理读写着问题的两种常见策略是:强读者同步和强写者同步。在强读者同步过程中,总是给读者优先权,只要写着当前没有进行写操作,读者就可以获得访问权。在强写者同步过程中,通常将优先权先交给写者,而将读者延迟到所有等待的或者活动的写者都完成为止。简单的说:
    (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_castTest*>(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_castTest*>(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; iTHREADS_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_castTest*>(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_castTest*>(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; iTHREADS_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:

点击(此处)折叠或打开

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

    参考:
         Linux 下的线程读写锁
        http://www.cppblog.com/bigsml/archive/2006/09/07/12137.html
 
相关文章
|
2月前
|
Linux API C++
【Linux C/C++ 线程同步 】Linux API 读写锁的编程使用
【Linux C/C++ 线程同步 】Linux API 读写锁的编程使用
21 1
|
4月前
|
Linux
Linux在文件特定偏移量处读写pread和pwrite
系统调用 pread()和 pwrite()完成与 read()和 write()相类似的工作,只是前两者会在 offset 参数所指定的位置进行文件 I/O 操作,而非始于文件的当前偏移量处,且它们不会改变文件的当前偏移量。
48 0
Linux在文件特定偏移量处读写pread和pwrite
|
4月前
|
Linux
Linux io多块读写readv函数和writev函数
fd参数是被操作的目标文件描述符。iov参数的类型是iovec结构数组,该结构体描述一块内存区。iovcnt参数是iov数组的长度,即有多少块内存数据需要从fd读出或写到fd。readv和writev在成功时返回读出/写入fd的字节数,失败则返回-1并设置errno。readv函数将数据从文件描述符读到分散的内存块中,即分散读;writev函数则将多块分散的内存数据一并写入文件描述符中,即集中写。
20 0
|
4月前
|
Linux
【Linux C 几种锁的性能对比】 1.读写锁 2.互斥锁 3.自旋锁 4.信号量 5.rcu
【Linux C 几种锁的性能对比】 1.读写锁 2.互斥锁 3.自旋锁 4.信号量 5.rcu
|
5月前
|
Linux
Linux线程同步(try锁和读写锁)
Linux线程同步(try锁和读写锁)
33 0
|
3月前
|
Linux
Linux多线程中互斥锁、读写锁、自旋锁、条件变量、信号量详解
Linux多线程中互斥锁、读写锁、自旋锁、条件变量、信号量详解
75 0
Linux多线程中互斥锁、读写锁、自旋锁、条件变量、信号量详解
|
7月前
|
移动开发 Linux Windows
linux系统中QT进行文本读写操作的方法
linux系统中QT进行文本读写操作的方法
54 0
|
9月前
|
Linux
Linux文件读写操作全面解析
在Linux系统中,文件读写操作是非常常见和重要的任务。无论是读取配置文件、处理日志文件还是进行数据持久化,文件读写都是必不可少的。本文将全面解析Linux下文件读写的各个方面,包括打开文件、读取文件内容、写入文件内容以及错误处理。我们将详细介绍相关的系统调用和C标准库函数,并提供丰富的代码示例。
529 0
|
10月前
|
Linux 编译器
Linux系统应用编程---线程同步基础(互斥量、死锁、读写锁)
Linux系统应用编程---线程同步基础(互斥量、死锁、读写锁)
92 0
|
11月前
|
存储 缓存 安全
Linux下线程同步(带你了解什么是互斥锁、死锁、读写锁、条件变量、信号量等)
Linux下线程同步(带你了解什么是互斥锁、死锁、读写锁、条件变量、信号量等)
123 0