缓冲区初始状态:
read不等于write。
生产者写满:
write==read,即将写的地方为刚读取的位置,就是下一个位置还没有读,所以代表写满。
消费者读完:
read+1=write,即将读的地方为即将写入得位置,还没有写,就不能再读了,这里就代表读完。
//信号量模型
#include
#include
#include
#include
//临界资源描述信息
struct
Data
{
int
d
[
5
]
;
//环形缓冲区
int
ptr_read
;
//已经读位置
int
ptr_write
;
//即将写位置
sem_t
can_read
;
//可读数据数目
sem_t
can_write
;
//可写数据数目
};
struct
Data
data
;
int
length
=
5
;
static
int
value
=
0
;
//作为环形缓冲区的数据
void
init_data
(
void
)
{
data
.
ptr_read
=
4
;
data
.
ptr_write
=
0
;
sem_init
(
&
data
.
can_read
,
0
,
0
);
sem_init
(
&
data
.
can_write
,
0
,
length
);
}
void
*
thread_consumer
(
void
*
arg
);
void
*
thread_producter
(
void
*
arg
);
int
main
()
{
init_data
();
/************创建消费者和生产者线程*******************/
pthread_t
consumer
,
producter
;
pthread_attr_t
attr
;
void
*
thread_result
;
/***设置线程为脱离类型***/
pthread_attr_init
(
&
attr
);
pthread_attr_setdetachstate
(
&
attr
,
PTHREAD_CREATE_DETACHED
);
/***创建消费者线程***/
pthread_create
(
&
consumer
,
&
attr
,
thread_consumer
,
NULL
);
/***创建生产者线程***/
pthread_create
(
&
producter
,
&
attr
,
thread_producter
,
NULL
);
while
(
1
)
{
sleep
(
2
);
}
}
void
*
thread_consumer
(
void
*
arg
)
{
int
count
=
0
;
while
(
1
)
{
/****随机的消费数据使得问题适应性更广*****/
int
sleep_time
=
rand
()
%
3
;
sleep
(
sleep_time
);
sem_wait
(
&
data
.
can_read
);
//减少可读信号量
printf
(
"sub data is = %d
\n
"
,
data
.
d
[(
data
.
ptr_read
+
1
)
%
length
]);
//读出数据
data
.
ptr_read
=
(
data
.
ptr_read
+
1
)
%
length
;
//更新已读位置
sem_post
(
&
data
.
can_write
);
//增加可写信号量
}
}
void
*
thread_producter
(
void
*
arg
)
{
int
count
=
0
;
while
(
1
)
{
int
sleep_time
=
rand
()
%
3
;
sleep
(
sleep_time
);
int
ret
=
sem_wait
(
&
data
.
can_write
);
//减少可写信号量
data
.
d
[
data
.
ptr_write
]
=++
value
;
//写入新的值
printf
(
"------add data is = %d
\n
"
,
data
.
d
[
data
.
ptr_write
]);
//打印新生产的值
data
.
ptr_write
=
(
data
.
ptr_write
+
1
)
%
length
;
//更新即将写入的位置
ret
=
sem_post
(
&
data
.
can_read
);
//增加可读信号量
}
}
//条件变量模型
#include
#include
#include
#include
//临界资源描述信息
struct
Data
{
int
d
[
5
]
;
//临界资源
int
ptr_read
;
//已经读指针位置
int
ptr_write
;
//即将写指针位置
pthread_mutex_t
mutex1
;
pthread_mutex_t
mutex2
;
pthread_cond_t
can_read
;
pthread_cond_t
can_write
;
};
static
int
value
=
0
;
struct
Data
data
;
int
length
=
5
;
void
init_data
(
void
)
{
data
.
ptr_read
=
4
;
data
.
ptr_write
=
0
;
pthread_cond_init
(
&
data
.
can_read
,
NULL
);
pthread_mutex_init
(
&
data
.
mutex1
,
NULL
);
pthread_cond_init
(
&
data
.
can_write
,
NULL
);
pthread_mutex_init
(
&
data
.
mutex2
,
NULL
);
}
void
*
thread_consumer
(
void
*
arg
);
void
*
thread_producter
(
void
*
arg
);
int
main
()
{
init_data
();
/************创建消费者和生产者线程*******************/
pthread_t
consumer
,
producter
;
pthread_attr_t
attr
;
void
*
thread_result
;
/***设置线程为脱离类型***/
pthread_attr_init
(
&
attr
);
pthread_attr_setdetachstate
(
&
attr
,
PTHREAD_CREATE_DETACHED
);
/***创建消费者线程***/
pthread_create
(
&
consumer
,
&
attr
,
thread_consumer
,
NULL
);
/***创建生产者线程***/
pthread_create
(
&
producter
,
&
attr
,
thread_producter
,
NULL
);
while
(
1
)
{
sleep
(
2
);
}
}
void
*
thread_consumer
(
void
*
arg
)
{
sleep
(
3
);
//消费者先睡眠2s,让生产者生产数据
while
(
1
)
{
/****随机的消费数据使得问题适应性更广*****/
int
sleep_time
=
rand
()
%
3
;
sleep
(
sleep_time
);
pthread_mutex_lock
(
&
data
.
mutex1
);
if
((
data
.
ptr_read
+
1
)
%
length
==
data
.
ptr_write
)
//即将读的位置还没有写好数据
pthread_cond_wait
(
&
data
.
can_read
,
&
data
.
mutex1
);
printf
(
"sub data:%d
\n
"
,
data
.
d
[(
data
.
ptr_read
+
1
)
%
length
]);
//唤醒后即可读取数据
data
.
ptr_read
=
(
data
.
ptr_read
+
1
)
%
length
;
//更新已经读取指针位置
pthread_cond_signal
(
&
data
.
can_write
);
pthread_mutex_unlock
(
&
data
.
mutex1
);
}
}
void
*
thread_producter
(
void
*
arg
)
{
int
count
=
0
;
while
(
1
)
{
int
sleep_time
=
rand
()
%
3
;
sleep
(
sleep_time
);
pthread_mutex_lock
(
&
data
.
mutex2
);
if
(
data
.
ptr_write
==
data
.
ptr_read
)
//生产者即将写的位置为消费者即将读的位置
pthread_cond_wait
(
&
data
.
can_write
,
&
data
.
mutex2
);
//等待消费者
data
.
d
[
data
.
ptr_write
]
=++
value
;
//写入数据
printf
(
"------add data:%d
\n
"
,
data
.
d
[
data
.
ptr_write
]);
data
.
ptr_write
=
(
data
.
ptr_write
+
1
)
%
length
;
//写指针后移
pthread_cond_signal
(
&
data
.
can_read
);
//通知消费者
pthread_mutex_unlock
(
&
data
.
mutex2
);
}
}
//线程消息模型
#include
#include
struct
Data
{
int
d
[
5
];
int
ptr_write
;
//将要写入数据的位置
int
ptr_read
;
//已经读取过数据的位置
int
can_write
;
int
can_read
;
};
pthread_t
thread1
,
thread2
;
struct
Data
data
;
int
value
=
0
;
int
length
=
5
;
void
*
producer
(
void
*
pvoid
)
{
int
signum
;
sigset_t
sig
;
sigemptyset
(
&
sig
);
sigaddset
(
&
sig
,
SIGUSR1
);
pthread_sigmask
(
SIG_BLOCK
,
&
sig
,
NULL
);
//设置该线程的信号屏蔽字为SIGUSR1
data
.
d
[
data
.
ptr_write
]
=++
value
;
printf
(
"produce new data : %d
\n
"
,
data
.
d
[
data
.
ptr_write
]);
data
.
ptr_write
=
(
data
.
ptr_write
+
1
)
%
length
;
while
(
1
)
{
sleep
(
rand
()
%
3
);
//随机睡眠
if
(
data
.
ptr_write
==
data
.
ptr_read
)
{
data
.
can_write
=
0
;
sigwait
(
&
sig
,
&
signum
);
//睡眠等待SIGUSR1信号的到来
}
data
.
d
[
data
.
ptr_write
]
=++
value
;
printf
(
"produce new data : %d
\n
"
,
data
.
d
[
data
.
ptr_write
]);
data
.
ptr_write
=
(
data
.
ptr_write
+
1
)
%
length
;
if
(
data
.
can_read
==
0
)
{
data
.
can_read
=
1
;
pthread_kill
(
thread2
,
SIGUSR2
);
}
}
}
void
*
consumer
(
void
*
pvoid
)
{
sleep
(
1
);
int
signum
;
sigset_t
sig
;
sigemptyset
(
&
sig
);
sigaddset
(
&
sig
,
SIGUSR2
);
pthread_sigmask
(
SIG_BLOCK
,
&
sig
,
NULL
);
//设置该线程的信号屏蔽字为SIGUSR2
while
(
1
)
{
sleep
(
rand
()
%
3
);
//随机睡眠
if
((
data
.
ptr_read
+
1
)
%
length
==
data
.
ptr_write
)
{
data
.
can_read
=
0
;
sigwait
(
&
sig
,
&
signum
);
//睡眠等待SIGUSR1信号的到来
}
printf
(
"------consumer new data : %d
\n
"
,
data
.
d
[(
data
.
ptr_read
+
1
)
%
length
]);
data
.
ptr_read
=
(
data
.
ptr_read
+
1
)
%
length
;
if
(
data
.
can_write
==
0
)
{
data
.
can_write
=
1
;
pthread_kill
(
thread1
,
SIGUSR1
);
}
}
}
void
main
()
{
data
.
ptr_read
=
4
;
data
.
ptr_write
=
0
;
data
.
can_read
=
0
;
data
.
can_write
=
1
;
struct
sigaction
act
;
act
.
sa_handler
=
SIG_IGN
;
sigemptyset
(
&
act
.
sa_mask
);
act
.
sa_flags
=
0
;
sigaction
(
SIGUSR1
,
&
act
,
0
);
//设置信号SIGUSR1的处理方式忽略
sigaction
(
SIGUSR2
,
&
act
,
0
);
//设置信号SIGUSR1的处理方式忽略
pthread_create
(
&
thread1
,
NULL
,
producer
,
NULL
);
pthread_create
(
&
thread2
,
NULL
,
consumer
,
NULL
);
pthread_detach
(
thread1
);
pthread_detach
(
thread2
);
while
(
1
)
{
sleep
(
2
);
}
}
本文属于转载,原创地址http://blog.csdn.net/qq_695538007/article/details/42834541