Unix下读者写者同步问题的模拟程序
2011-01-22 16:05
375 查看
p { margin-bottom: 0.21cm; }
/*
*
ReaderWriter.c
*
题目
:2
:
*
Unix
下读者写者同步问题的模拟程序
要求
4
个读进程
2
个写进程。
*
采用信号量方式实现。可以采用
Pthread
多线程编程。
*
*
Created on: 2011-1-17
*
Author: banxi1988
*
*
信号量通信机制主要用来实现进程间同步
,
信号
量值用来标识系统可用 资源的个数
*
例如可以使用信号号来标识一个缓冲区空间的大小
,(
假定缓冲区空间大小为
256
个字节
.
*
在没有使用之前
,
该缓冲区没有任何内容
,
可用资源为
256,
即可以初始化信号
量为
256,
*
每向缓冲区写入一个字符
,
信号量的值自动减
1,
当信号量的值为
0
时
,
即表示缓冲区满
.
*
资源暂不可用
.
每从缓冲区读出一个字符
,
信号
时自动加
1,
如果信号量的值为
256,
则表示
*
缓冲区中没有内容
,
不可读
.
*
信号量初始化函数参考
:
*
// Initialize semaphore object SEM to VALUE. If PSHARED then
share it
//
with other processes.
extern
int
sem_init (sem_t *__sem,
int
__pshared, unsigned
int
__value)
简单翻译如下
,
将信号量对象
SEM
初始化为
VALUE
值
,
当信号量的值达到
PSHARED
时
,
将其分享给其它进程
.
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<unistd.h>
#include
<pthread.h>
#include
<time.h>
#include
<semaphore.h>
#define
WRITER 2
//
写者数量
.
2
#define
READER 4
//
读者数量
4
#define
BUFFER_SIZE 8
//
缓冲区
(
大小
为
8
)
int
writeOffset = 0;
//
写者写内容的位置
int
readOffset = 0;
//
读者取内容的位置
int
buffer[BUFFER_SIZE] = {
'#'
};
// '#'
字符代表空间没有内容
sem_t
empty_sem;
//
同步信号量,
当满了时阻止写者写
.
sem_t
full_sem;
//
同步信号量,
当没有内容时阻止读者读
pthread_mutex_t
mutexlock;
//
互斥锁,
一次只有一个线程访问缓冲
char
letters[52] =
{
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
};
/*
*
打印缓冲情况
*/
void
printBuffer
()
{
int
i;
printf
(
"/t
当前缓冲区内容
:/t"
);
for
(i = 0; i < BUFFER_SIZE; i++)
printf
(
"%c
"
,
buffer[i]);
printf
(
"/n"
);
}
void
writer
(
int
*id) {
srand
((
unsigned
)
time(NULL));
int
index = 0;
while
(1) {
sleep
(1);
//
先等待
//sem_wait(
&empty_sem
);//
等待缓冲区可写信号
.
pthread_mutex_lock
(&mutexlock);
//
下面的条件语句为
if
时一位读写者
,
一次读写一个字母
.
改为
while
时则不同
.
if
(buffer[writeOffset
% BUFFER_SIZE] ==
'#'
)
{
//
如果有空间可写
index
=
rand
()
% 52;
writeOffset
= writeOffset % BUFFER_SIZE;
buffer[writeOffset]
= letters[index];
printf
(
"
第
%2d
位写者写了一个字母
%c
/n"
,
*id,buffer[writeOffset]);
printBuffer();
++writeOffset;
}
//WHILE
//
传递出
,
已经生产满的信号
.
然后解锁
//sem_post(
&full_sem
);
pthread_mutex_unlock
(&mutexlock);
}
}
void
reader
(
int
*id) {
while
(1) {
sleep
(1);
//sem_wait(
&full_sem
);//
等待写者写好的信号
pthread_mutex_lock
(&mutexlock);
//
if
(buffer[readOffset
% BUFFER_SIZE] !=
'#'
)
{
//
有东西
可读
printf
(
"
第
%2d
位读者读出了一个字母
%c
/n"
,
*id,buffer[readOffset]);
readOffset
= readOffset % BUFFER_SIZE;
buffer[readOffset]
=
'#'
;
++readOffset;
}
//sem_post(
&empty_sem
);
pthread_mutex_unlock
(&mutexlock);
}
}
int
main
()
{
pthread_t
writePID[WRITER];
//2
pthread_t
readerPID[READER];
//4
int
ret;
//
ret
~ return value
int
i;
//for
loop
int
wID[WRITER];
//
读者与写者的编号
,
因为线程的标识符太长了
,
不好看
.
int
rID[READER];
/**
*
初始化同步信号量
*/
ret
=
sem_init
(&empty_sem,
0, BUFFER_SIZE);
if
(ret != 0) {
perror
(
"
sem
init
failed /n"
);
exit
(EXIT_FAILURE);
}
ret
=
sem_init
(&full_sem,
0, BUFFER_SIZE);
if
(ret != 0) {
perror
(
"
sem
init
failed /n"
);
exit
(EXIT_FAILURE);
}
/**
*
初始化互斥信号量
*/
ret
=
pthread_mutex_init
(&mutexlock,NULL);
if
(ret != 0) {
perror
(
"
mutexlock
init
failed /n"
);
exit
(EXIT_FAILURE);
}
/***
*
初始缓冲区的内容
*/
for
(i
= 0; i < BUFFER_SIZE;i++){
buffer[i]
=
'#'
;
}
printBuffer();
//
打印开始时候缓冲区的内容
:
/**
*
创建
WRITER(2)
个写者线程
*/
for
(i = 0; i < WRITER; i++) {
wID[i]
= i+1;
ret
=
pthread_create
(&writePID[i],
NULL, (
void
*) *writer, &wID[i]);
if
(ret != 0) {
perror
(
"writer
create failed /n"
);
exit
(EXIT_FAILURE);
}
}
/**
*
创建
READER(4)
个消费者线程
*/
for
(i = 0; i < READER; i++) {
rID[i]
= i+1;
ret
=
pthread_create
(&readerPID[i],
NULL, (
void
*) *reader, &rID[i]);
if
(ret != 0) {
perror
(
"reader
create failed /n"
);
exit
(EXIT_FAILURE);
}
}
/**
*
等待线程完成
.
*/
for
(i = 0; i < WRITER; i++) {
pthread_join
(writePID[i],
NULL);
}
for
(i = 0; i < READER; i++) {
pthread_join
(readerPID[i],
NULL);
}
exit
(EXIT_SUCCESS);
}
/***
*
编译运行命令
:
*
banxi
@
banxi
:~/
jeework
/
pthread
$
gcc
-g -o
rwer
ReaderWriter.c -
lpthread
*
*
下面是运行结果及分析
:
总共有五不同次测试结果及分析
.
*
banxi1@
banxi
:~/
jeework
/
pthread
$
./
rwer
当前缓冲区内容
: #
# # # # # # #
第
1
位写者写了一个字母
F
当前缓冲区内容
: F
# # # # # # #
第
1
位读者读出了一个字母
F
第
2
位写者写了一个字母
n
当前缓冲区内容
: #
n # # # # # #
第
2
位读者读出了一个字母
n
第
1
位写者写了一个字母
C
当前缓冲区内容
: #
# C # # # # #
第
3
位读者读出了一个字母
C
第
2
位写者写了一个字母
X
当前缓冲区内容
: #
# # X # # # #
第
4
位读者读出了一个字母
X
第
1
位写者写了一个字母
c
当前缓冲区内容
: #
# # # c # # #
^C
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
(
说明
:
因为程序没有自己终止
,
所以用
CTRL+C
来中断
.)
ret
= sem_init(
&full_sem
,
0, 0);
由于上面对于
full_sem
的初始值为
0,
终止值也是为
0,
所以出现
,
了读出一个写一个的状态
,
而不是写满之后再读完
.
一个读者一次读写一次的话
,
也是程序为了容易观察结果而设定的
.
因为判断是
if.
如果改成
while
就会不同了
.
将在下面对其进行测试
.
但把上面的改为如下的
:
ret
= sem_init(
&full_sem
,0,BUFFER_SIZE);
时程序运行结果如下
:
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
./
rwer
当前缓冲区内容
: #
# # # # # # #
第
1
写者写了一个字母
p
当前缓冲区内容
: p
# # # # # # #
第
1
位读者读出了一个字母
p
第
2
写者写了一个字母
X
当前缓冲区内容
: #
X # # # # # #
第
2
位读者读出了一个字母
X
第
1
写者写了一个字母
t
当前缓冲区内容
: #
# t # # # # #
第
2
写者写了一个字母
t
当前缓冲区内容
: #
# t t # # # #
第
4
位读者读出了一个字母
t
第
3
位读者读出了一个字母
t
第
1
写者写了一个字母
M
当前缓冲区内容
: #
# # # M # # #
第
2
写者写了一个字母
J
当前缓冲区内容
: #
# # # M J # #
第
2
位读者读出了一个字母
M
第
3
位读者读出了一个字母
J
第
1
写者写了一个字母
Y
当前缓冲区内容
: #
# # # # # Y #
第
2
写者写了一个字母
m
测试结果三
:
将上面的条件设置
while
时的结果
:
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
./
rwer
当前缓冲区内容
: #
# # # # # # #
第
2
位写者写了一个字母
p
当前缓冲区内容
: p
# # # # # # #
第
2
位写者写了一个字母
W
当前缓冲区内容
: p
W # # # # # #
第
2
位写者写了一个字母
r
当前缓冲区内容
: p
W r # # # # #
第
2
位写者写了一个字母
e
当前缓冲区内容
: p
W r e # # # #
第
2
位写者写了一个字母
d
当前缓冲区内容
: p
W r e d # # #
第
2
位写者写了一个字母
Z
当前缓冲区内容
: p
W r e d Z # #
第
2
位写者写了一个字母
G
当前缓冲区内容
: p
W r e d Z G #
第
2
位写者写了一个字母
s
当前缓冲区内容
: p
W r e d Z G s
第
4
位读者读出了一个字母
p
第
4
位读者读出了一个字母
W
第
4
位读者读出了一个字母
r
第
4
位读者读出了一个字母
e
第
4
位读者读出了一个字母
d
第
4
位读者读出了一个字母
Z
第
4
位读者读出了一个字母
G
第
4
位读者读出了一个字母
s
第
1
位写者写了一个字母
e
当前缓冲区内容
: e
# # # # # # #
第
1
位写者写了一个字母
F
当前缓冲区内容
: e
F # # # # # #
第
1
位写者写了一个字母
E
当前缓冲区内容
: e
F E # # # # #
第
1
位写者写了一个字母
N
当前缓冲区内容
: e
F E N # # # #
第
1
位写者写了一个字母
I
当前缓冲区内容
: e
F E N I # # #
第
1
位写者写了一个字母
A
当前缓冲区内容
: e
F E N I A # #
第
1
位写者写了一个字母
Y
当前缓冲区内容
: e
F E N I A Y #
第
1
位写者写了一个字母
U
当前缓冲区内容
: e
F E N I A Y U
^C
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
运行结果四
:
去掉了待等待
相应信号量的代码
..
这样的话读写的控制就又
if
或者
while
来判断了
.
这个一来
,sleep
就必不可少
,
因为只有在一个线程
sleep
和时候
,
其它的线程才有抢占线程的平均的机会
.
为什么说平均呢
,
因为当写满或者读完的时候
,
线程也会释放掉锁的
.
但是马上又加入了抢点锁的过程
.
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
./
sigwrer
当前缓冲区内容
: #
# # # # # # #
第
1
位写者写了一个字母
s
当前缓冲区内容
: s
# # # # # # #
第
2
位读者读出了一个字母
s
第
2
位写者写了一个字母
h
当前缓冲区内容
: #
h # # # # # #
第
1
位读者读出了一个字母
h
第
1
位写者写了一个字母
Y
当前缓冲区内容
: #
# Y # # # # #
第
2
位读者读出了一个字母
Y
第
2
位写者写了一个字母
I
当前缓冲区内容
: #
# # I # # # #
第
1
位读者读出了一个字母
I
第
1
位写者写了一个字母
D
当前缓冲区内容
: #
# # # D # # #
第
2
位读者读出了一个字母
D
第
2
位写者写了一个字母
Q
当前缓冲区内容
: #
# # # # Q # #
第
3
位读者读出了一个字母
Q
第
1
位写者写了一个字母
c
当前缓冲区内容
: #
# # # # # c #
第
2
位写者写了一个字母
z
^C
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
运行结果五
:
这个是将线程的信号量全都注释掉之后的代码
.
发现
,
读写纯种不再是交互执行的了
.
不过还是存在某些规律的
,
比如
,
先写的然后读的
.
这个也许是调度问题吧
..
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
gcc
-g -o
sigwrer
ReaderWriter.c -
lpthread
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
./
sigwrer
当前缓冲区内容
: #
# # # # # # #
第
2
位写者写了一个字母
M
当前缓冲区内容
: M
# # # # # # #
第
1
位写者写了一个字母
m
当前缓冲区内容
: M
m # # # # # #
第
1
位读者读出了一个字母
M
第
2
位读者读出了一个字母
m
第
2
位写者写了一个字母
v
当前缓冲区内容
: #
# v # # # # #
第
1
位写者写了一个字母
p
当前缓冲区内容
: #
# v p # # # #
第
2
位读者读出了一个字母
v
第
1
位读者读出了一个字母
p
第
2
位写者写了一个字母
O
当前缓冲区内容
: #
# # # O # # #
第
1
位写者写了一个字母
A
当前缓冲区内容
: #
# # # O A # #
第
2
位读者读出了一个字母
O
第
1
位读者读出了一个字母
A
第
2
位写者写了一个字母
y
当前缓冲区内容
: #
# # # # # y #
^C
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
*
*/
/*
*
ReaderWriter.c
*
题目
:2
:
*
Unix
下读者写者同步问题的模拟程序
要求
4
个读进程
2
个写进程。
*
采用信号量方式实现。可以采用
Pthread
多线程编程。
*
*
Created on: 2011-1-17
*
Author: banxi1988
*
*
信号量通信机制主要用来实现进程间同步
,
信号
量值用来标识系统可用 资源的个数
*
例如可以使用信号号来标识一个缓冲区空间的大小
,(
假定缓冲区空间大小为
256
个字节
.
*
在没有使用之前
,
该缓冲区没有任何内容
,
可用资源为
256,
即可以初始化信号
量为
256,
*
每向缓冲区写入一个字符
,
信号量的值自动减
1,
当信号量的值为
0
时
,
即表示缓冲区满
.
*
资源暂不可用
.
每从缓冲区读出一个字符
,
信号
时自动加
1,
如果信号量的值为
256,
则表示
*
缓冲区中没有内容
,
不可读
.
*
信号量初始化函数参考
:
*
// Initialize semaphore object SEM to VALUE. If PSHARED then
share it
//
with other processes.
extern
int
sem_init (sem_t *__sem,
int
__pshared, unsigned
int
__value)
简单翻译如下
,
将信号量对象
SEM
初始化为
VALUE
值
,
当信号量的值达到
PSHARED
时
,
将其分享给其它进程
.
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<unistd.h>
#include
<pthread.h>
#include
<time.h>
#include
<semaphore.h>
#define
WRITER 2
//
写者数量
.
2
#define
READER 4
//
读者数量
4
#define
BUFFER_SIZE 8
//
缓冲区
(
大小
为
8
)
int
writeOffset = 0;
//
写者写内容的位置
int
readOffset = 0;
//
读者取内容的位置
int
buffer[BUFFER_SIZE] = {
'#'
};
// '#'
字符代表空间没有内容
sem_t
empty_sem;
//
同步信号量,
当满了时阻止写者写
.
sem_t
full_sem;
//
同步信号量,
当没有内容时阻止读者读
pthread_mutex_t
mutexlock;
//
互斥锁,
一次只有一个线程访问缓冲
char
letters[52] =
{
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
};
/*
*
打印缓冲情况
*/
void
printBuffer
()
{
int
i;
printf
(
"/t
当前缓冲区内容
:/t"
);
for
(i = 0; i < BUFFER_SIZE; i++)
printf
(
"%c
"
,
buffer[i]);
printf
(
"/n"
);
}
void
writer
(
int
*id) {
srand
((
unsigned
)
time(NULL));
int
index = 0;
while
(1) {
sleep
(1);
//
先等待
//sem_wait(
&empty_sem
);//
等待缓冲区可写信号
.
pthread_mutex_lock
(&mutexlock);
//
下面的条件语句为
if
时一位读写者
,
一次读写一个字母
.
改为
while
时则不同
.
if
(buffer[writeOffset
% BUFFER_SIZE] ==
'#'
)
{
//
如果有空间可写
index
=
rand
()
% 52;
writeOffset
= writeOffset % BUFFER_SIZE;
buffer[writeOffset]
= letters[index];
printf
(
"
第
%2d
位写者写了一个字母
%c
/n"
,
*id,buffer[writeOffset]);
printBuffer();
++writeOffset;
}
//WHILE
//
传递出
,
已经生产满的信号
.
然后解锁
//sem_post(
&full_sem
);
pthread_mutex_unlock
(&mutexlock);
}
}
void
reader
(
int
*id) {
while
(1) {
sleep
(1);
//sem_wait(
&full_sem
);//
等待写者写好的信号
pthread_mutex_lock
(&mutexlock);
//
if
(buffer[readOffset
% BUFFER_SIZE] !=
'#'
)
{
//
有东西
可读
printf
(
"
第
%2d
位读者读出了一个字母
%c
/n"
,
*id,buffer[readOffset]);
readOffset
= readOffset % BUFFER_SIZE;
buffer[readOffset]
=
'#'
;
++readOffset;
}
//sem_post(
&empty_sem
);
pthread_mutex_unlock
(&mutexlock);
}
}
int
main
()
{
pthread_t
writePID[WRITER];
//2
pthread_t
readerPID[READER];
//4
int
ret;
//
ret
~ return value
int
i;
//for
loop
int
wID[WRITER];
//
读者与写者的编号
,
因为线程的标识符太长了
,
不好看
.
int
rID[READER];
/**
*
初始化同步信号量
*/
ret
=
sem_init
(&empty_sem,
0, BUFFER_SIZE);
if
(ret != 0) {
perror
(
"
sem
init
failed /n"
);
exit
(EXIT_FAILURE);
}
ret
=
sem_init
(&full_sem,
0, BUFFER_SIZE);
if
(ret != 0) {
perror
(
"
sem
init
failed /n"
);
exit
(EXIT_FAILURE);
}
/**
*
初始化互斥信号量
*/
ret
=
pthread_mutex_init
(&mutexlock,NULL);
if
(ret != 0) {
perror
(
"
mutexlock
init
failed /n"
);
exit
(EXIT_FAILURE);
}
/***
*
初始缓冲区的内容
*/
for
(i
= 0; i < BUFFER_SIZE;i++){
buffer[i]
=
'#'
;
}
printBuffer();
//
打印开始时候缓冲区的内容
:
/**
*
创建
WRITER(2)
个写者线程
*/
for
(i = 0; i < WRITER; i++) {
wID[i]
= i+1;
ret
=
pthread_create
(&writePID[i],
NULL, (
void
*) *writer, &wID[i]);
if
(ret != 0) {
perror
(
"writer
create failed /n"
);
exit
(EXIT_FAILURE);
}
}
/**
*
创建
READER(4)
个消费者线程
*/
for
(i = 0; i < READER; i++) {
rID[i]
= i+1;
ret
=
pthread_create
(&readerPID[i],
NULL, (
void
*) *reader, &rID[i]);
if
(ret != 0) {
perror
(
"reader
create failed /n"
);
exit
(EXIT_FAILURE);
}
}
/**
*
等待线程完成
.
*/
for
(i = 0; i < WRITER; i++) {
pthread_join
(writePID[i],
NULL);
}
for
(i = 0; i < READER; i++) {
pthread_join
(readerPID[i],
NULL);
}
exit
(EXIT_SUCCESS);
}
/***
*
编译运行命令
:
*
banxi
@
banxi
:~/
jeework
/
pthread
$
gcc
-g -o
rwer
ReaderWriter.c -
lpthread
*
*
下面是运行结果及分析
:
总共有五不同次测试结果及分析
.
*
banxi1@
banxi
:~/
jeework
/
pthread
$
./
rwer
当前缓冲区内容
: #
# # # # # # #
第
1
位写者写了一个字母
F
当前缓冲区内容
: F
# # # # # # #
第
1
位读者读出了一个字母
F
第
2
位写者写了一个字母
n
当前缓冲区内容
: #
n # # # # # #
第
2
位读者读出了一个字母
n
第
1
位写者写了一个字母
C
当前缓冲区内容
: #
# C # # # # #
第
3
位读者读出了一个字母
C
第
2
位写者写了一个字母
X
当前缓冲区内容
: #
# # X # # # #
第
4
位读者读出了一个字母
X
第
1
位写者写了一个字母
c
当前缓冲区内容
: #
# # # c # # #
^C
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
(
说明
:
因为程序没有自己终止
,
所以用
CTRL+C
来中断
.)
ret
= sem_init(
&full_sem
,
0, 0);
由于上面对于
full_sem
的初始值为
0,
终止值也是为
0,
所以出现
,
了读出一个写一个的状态
,
而不是写满之后再读完
.
一个读者一次读写一次的话
,
也是程序为了容易观察结果而设定的
.
因为判断是
if.
如果改成
while
就会不同了
.
将在下面对其进行测试
.
但把上面的改为如下的
:
ret
= sem_init(
&full_sem
,0,BUFFER_SIZE);
时程序运行结果如下
:
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
./
rwer
当前缓冲区内容
: #
# # # # # # #
第
1
写者写了一个字母
p
当前缓冲区内容
: p
# # # # # # #
第
1
位读者读出了一个字母
p
第
2
写者写了一个字母
X
当前缓冲区内容
: #
X # # # # # #
第
2
位读者读出了一个字母
X
第
1
写者写了一个字母
t
当前缓冲区内容
: #
# t # # # # #
第
2
写者写了一个字母
t
当前缓冲区内容
: #
# t t # # # #
第
4
位读者读出了一个字母
t
第
3
位读者读出了一个字母
t
第
1
写者写了一个字母
M
当前缓冲区内容
: #
# # # M # # #
第
2
写者写了一个字母
J
当前缓冲区内容
: #
# # # M J # #
第
2
位读者读出了一个字母
M
第
3
位读者读出了一个字母
J
第
1
写者写了一个字母
Y
当前缓冲区内容
: #
# # # # # Y #
第
2
写者写了一个字母
m
测试结果三
:
将上面的条件设置
while
时的结果
:
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
./
rwer
当前缓冲区内容
: #
# # # # # # #
第
2
位写者写了一个字母
p
当前缓冲区内容
: p
# # # # # # #
第
2
位写者写了一个字母
W
当前缓冲区内容
: p
W # # # # # #
第
2
位写者写了一个字母
r
当前缓冲区内容
: p
W r # # # # #
第
2
位写者写了一个字母
e
当前缓冲区内容
: p
W r e # # # #
第
2
位写者写了一个字母
d
当前缓冲区内容
: p
W r e d # # #
第
2
位写者写了一个字母
Z
当前缓冲区内容
: p
W r e d Z # #
第
2
位写者写了一个字母
G
当前缓冲区内容
: p
W r e d Z G #
第
2
位写者写了一个字母
s
当前缓冲区内容
: p
W r e d Z G s
第
4
位读者读出了一个字母
p
第
4
位读者读出了一个字母
W
第
4
位读者读出了一个字母
r
第
4
位读者读出了一个字母
e
第
4
位读者读出了一个字母
d
第
4
位读者读出了一个字母
Z
第
4
位读者读出了一个字母
G
第
4
位读者读出了一个字母
s
第
1
位写者写了一个字母
e
当前缓冲区内容
: e
# # # # # # #
第
1
位写者写了一个字母
F
当前缓冲区内容
: e
F # # # # # #
第
1
位写者写了一个字母
E
当前缓冲区内容
: e
F E # # # # #
第
1
位写者写了一个字母
N
当前缓冲区内容
: e
F E N # # # #
第
1
位写者写了一个字母
I
当前缓冲区内容
: e
F E N I # # #
第
1
位写者写了一个字母
A
当前缓冲区内容
: e
F E N I A # #
第
1
位写者写了一个字母
Y
当前缓冲区内容
: e
F E N I A Y #
第
1
位写者写了一个字母
U
当前缓冲区内容
: e
F E N I A Y U
^C
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
运行结果四
:
去掉了待等待
相应信号量的代码
..
这样的话读写的控制就又
if
或者
while
来判断了
.
这个一来
,sleep
就必不可少
,
因为只有在一个线程
sleep
和时候
,
其它的线程才有抢占线程的平均的机会
.
为什么说平均呢
,
因为当写满或者读完的时候
,
线程也会释放掉锁的
.
但是马上又加入了抢点锁的过程
.
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
./
sigwrer
当前缓冲区内容
: #
# # # # # # #
第
1
位写者写了一个字母
s
当前缓冲区内容
: s
# # # # # # #
第
2
位读者读出了一个字母
s
第
2
位写者写了一个字母
h
当前缓冲区内容
: #
h # # # # # #
第
1
位读者读出了一个字母
h
第
1
位写者写了一个字母
Y
当前缓冲区内容
: #
# Y # # # # #
第
2
位读者读出了一个字母
Y
第
2
位写者写了一个字母
I
当前缓冲区内容
: #
# # I # # # #
第
1
位读者读出了一个字母
I
第
1
位写者写了一个字母
D
当前缓冲区内容
: #
# # # D # # #
第
2
位读者读出了一个字母
D
第
2
位写者写了一个字母
Q
当前缓冲区内容
: #
# # # # Q # #
第
3
位读者读出了一个字母
Q
第
1
位写者写了一个字母
c
当前缓冲区内容
: #
# # # # # c #
第
2
位写者写了一个字母
z
^C
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
运行结果五
:
这个是将线程的信号量全都注释掉之后的代码
.
发现
,
读写纯种不再是交互执行的了
.
不过还是存在某些规律的
,
比如
,
先写的然后读的
.
这个也许是调度问题吧
..
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
gcc
-g -o
sigwrer
ReaderWriter.c -
lpthread
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
./
sigwrer
当前缓冲区内容
: #
# # # # # # #
第
2
位写者写了一个字母
M
当前缓冲区内容
: M
# # # # # # #
第
1
位写者写了一个字母
m
当前缓冲区内容
: M
m # # # # # #
第
1
位读者读出了一个字母
M
第
2
位读者读出了一个字母
m
第
2
位写者写了一个字母
v
当前缓冲区内容
: #
# v # # # # #
第
1
位写者写了一个字母
p
当前缓冲区内容
: #
# v p # # # #
第
2
位读者读出了一个字母
v
第
1
位读者读出了一个字母
p
第
2
位写者写了一个字母
O
当前缓冲区内容
: #
# # # O # # #
第
1
位写者写了一个字母
A
当前缓冲区内容
: #
# # # O A # #
第
2
位读者读出了一个字母
O
第
1
位读者读出了一个字母
A
第
2
位写者写了一个字母
y
当前缓冲区内容
: #
# # # # # y #
^C
banxi1988@banxi1988-desktop:~/
jeework
/
pthread
$
*
*/
相关文章推荐
- 编制模拟“五个哲学家”问题的程序(unix操作系统系)---4
- 进程、线程知识点总结和同步(消费者生产者,读者写者三类问题)、互斥、异步、并发、并行、死锁、活锁的总结
- 读者与写者同步问题
- 基于信号量与P/V操作同步机制的读者/写者问题的设计与实现 (写者优先)
- (转)很有借鉴意义!读者写者问题--使用信号量的读者优先与写者优先程序分析
- 进程、线程知识点总结和同步(消费者生产者,读者写者三类问题)、互斥、异步、并发、并行、死锁、活锁的总结
- 进程同步互斥——读者写者问题
- 经典同步问题linux下的C实现:生产者-消费者问题,读者-写者问题,哲学家问题
- 基于信号量与P/V操作同步机制的读者/写者问题的设计与实现 (写者优先)
- 【Linux学习笔记】39:Linux下C模拟读者写者问题
- 读者写者问题--使用信号量的读者优先与写者优先程序分析
- 操作系统进程同步互斥经典问题之读者写者问题
- 操作系统同步互斥经典问题——读者写者问题
- 进程同步问题(1)——生产者,消费者 & 读者,写者问题
- 操作系统进程同步三大问题:生产者消费者,哲学家进餐,读者写者问题
- wait, notify, notifyAll, 简单数组模拟队列实现读者写者问题。
- 读者写者问题--使用信号量的读者优先与写者优先程序分析
- 操作系统笔记《7》-------生产者、消费者问题 。读者、写者问题 程序实现
- 经典同步问题--读者和写者问题
- Linux 关于读者与写者同步互斥问题的解析