线程读写锁解决读者-写者问题

本文介绍了一种利用读写锁解决读者写者问题的方法,通过C语言实现了一个简单的示例程序,并解释了读写锁的工作原理及其实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  这个程序是前段时间学习线程间同步的时候写的,利用读写锁来实现的(我感觉读写锁就是专门为这类问题而生的):

 1  /* *
 2  *读者写者问题
 3  *问题描述
 4  *1)允许多位读者同时访问某数据,但是同一时间,只允许一位写者写入数据
 5  *2)当没有读者在读取数据的时候,才允许写者写入数据
 6  *3)当有写者正在写入数据的时候,不允许读者进行数据的读写
 7  *History:
 8  *2010/03/16    huangwei    First release
 9  */
10 
11  #include < stdio.h >
12  #include < unistd.h >
13  #include < pthread.h >
14 
15  #define         READER_MAX    3        /*最多允许多少人一起读取数据*/
16  #define         WRITER_MAX    2        /*最多允许多少人写数据*/
17 
18  pthread_rwlock_t    rw_lock;         /* 读写锁 */
19 
20  /* *
21  *reader_thread - 模拟读者进行数据读取
22  *@arg :  没有使用
23  */
24 
25  void *  reader_thread( void   * arg)
26  {
27       while ( 1 ) {
28           /* 尝试加只读锁 */         
29           if (pthread_rwlock_tryrdlock( & rw_lock)) {
30               /* 加只读锁不成功,打印信息,1秒钟后继续尝试 */
31              printf( " 读\t者%u暂时不能读取数据.\n " , (unsigned  int )pthread_self());
32              sleep( 1 );
33          }  else  {
34               /* 加只读锁成功,显示哪位读者正在进行数据读取 */
35              printf( " 读\t者%u正在读取数据.\n " , (unsigned  int )pthread_self());
36              sleep( 1 );     /* 读者正在读取数据 */
37              printf( " 读\t者%u读取数据完毕.\n " , (unsigned  int )pthread_self());
38              pthread_rwlock_unlock( & rw_lock);  /* 解只读锁 */
39              sleep( 2 );     /* 休息一段时间后再尝试进行数据读取 */
40          }    
41      }
42  }
43 
44  /* *
45  *writer_thread -  模拟写者写入数据
46  *@arg : 没有使用
47  */
48 
49  void *  writer_thread( void   * arg)
50  {
51       while ( 1 ) {
52           /* 尝试加写锁 */
53           if (pthread_rwlock_trywrlock( & rw_lock)) {
54               /* 加写锁不成功,输出信息,2秒后再继续尝试 */
55              printf( " 写者%u暂时不能写入数据\n " , (unsigned  int )pthread_self());
56              sleep( 2 );
57          }  else  {
58               /* 加写锁成功,显示目前哪为写者正在进行数据写入 */
59              printf( " 写者%u正在写入数据.\n " , (unsigned  int )pthread_self());
60              sleep( 2 );     /* 写者正在写入数据 */
61              printf( " 写者%u写入数据完毕.\n " , (unsigned  int )pthread_self());
62              pthread_rwlock_unlock( & rw_lock);
63              sleep( 3 );     /* 休息一段时间后再尝试进行数据写入 */
64          }
65      }
66  }
67 
68  int  main( int  argc,  char *  argv[])
69  {
70      pthread_t reader, writer;              /* 记录读者和写者的线程号 */
71      
72       int  i  =   0 ;                           /* 循环变量 */
73      
74      pthread_rwlock_init( & rw_lock, NULL);     /* 初始化读写锁 */
75      
76       /* 创建READER_MAX个读者 */
77       for (i  =   0 ; i  <  READER_MAX; i ++ )    
78          pthread_create( & reader, NULL, ( void   * )reader_thread, NULL);
79 
80       /* 创建WRITER_MAX个读者 */
81       for (i  =   0 ; i  <  WRITER_MAX; i ++ )
82          pthread_create( & writer, NULL, ( void   * )writer_thread, NULL);
83      
84      sleep( 10 );                           /* 程序运行10秒后退出 */
85      
86       return   0 ;
87  }


 看看读写锁的结构体定义:

typedef  struct  {

volatile  unsigned  int   lock ;
#if  SPINLOCK_DEBUG  // 用于调试
unsigned magic;
#endif
} rwlock_t;

其基本上是用汇编实现的,这里说说其大体的过程:

  初始化的时候,给lock赋值为0x0100 0000,也就是允许的读者的最大个数.加读锁的时候,只要这个值减1后不为负,那么就能得到 该锁。而加写锁的时候,比较这个这个值是否等于0x0100 0000,如果是的话,就直接锁住总线,不让其他线程访问内存,只要就 实现了资源的独占。

  读写锁更详细的信息可以看看IBM社区的这篇文章,我觉得写得非常好:http://www.ibm.com/developerworks/cn/linux/l-rwlock_writing/index.html

 

转载于:https://www.cnblogs.com/huangwei/archive/2010/05/19/1739659.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值