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