易网时代-编程资源站
Welcome
微信登录
编程资源
图片资源库
蚂蚁家优选
PDF转换器
软件资源
软件开发
、
小程序制作
、
系统集成与运维
、
空间租用
、
硬件开发
、
视频监控
、
技术咨询与支持
——联系电话:0311-88999002/88999003
首页
/
操作系统
/
Linux
/
使用POSIX线程解决“生产者/消费者”问题
使用POSIX线程解决“生产者/消费者”问题:
/*
* File : pc.cpp
*
* Title : Demo Producer/Consumer.
*
* Short : A solution to the producer consumer problem using pthreads.
* This is a simple FIFO pipe between two tasks. The primary problem is
* ensuring that the producer blocks if the FIFO is full, and the consumer
* blocks if it is empty, and avoiding data-races along the way. A secondary
* concern is that there is as little interference between the two tasks as
* possible.
*
* Author : Andrae Muys
*
* Date : 18 September 1997
*/
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#ifdef _WIN32
# include <windows.h>
# define SLEEP(ms) Sleep(ms)
#elif defined(LINUX)
# include <unistd.h>
# define SLEEP(ms) sleep(ms)
#endif
#define QUEUE_SIZE 10
#define LOOP 20
void
* producer (
void
*args);
void
* consumer (
void
*args);
typedef
struct
{
int
buf[QUEUE_SIZE];
long
head, tail;
bool
full, empty;
pthread_mutex_t *mutex;
pthread_cond_t *notFull, *notEmpty;
} Queue;
Queue* queueInit (
void
);
void
queueDelete (Queue *q);
void
queueAdd (Queue *q,
int
in);
void
queueDel (Queue *q,
int
*out);
int
main(
int
argc,
char
* argv[])
{
Queue* fifo = queueInit ();
assert(fifo != NULL);
pthread_t pro, con;
pthread_create (&pro, NULL, &producer, fifo);
pthread_create (&con, NULL, &consumer, fifo);
pthread_join (pro, NULL);
pthread_join (con, NULL);
queueDelete (fifo);
return
0;
}
void
* producer (
void
*q)
{
Queue* fifo = (Queue *)q;
for
(
int
i = 0; i < LOOP; i++)
{
// 临界区操作:若队列未满,添加新数据
pthread_mutex_lock (fifo->mutex);
while
(fifo->full)
{
printf (
"producer: Queue FULL. "
);
pthread_cond_wait (fifo->notFull, fifo->mutex);
}
queueAdd (fifo, i);
pthread_mutex_unlock (fifo->mutex);
// 数据添加结束,发“队列有数据”信号
pthread_cond_signal (fifo->notEmpty);
SLEEP (100);
}
// 与上面类似
for
(
int
i = 0; i < LOOP; i++)
{
pthread_mutex_lock (fifo->mutex);
while
(fifo->full)
{
printf (
"producer: Queue FULL. "
);
pthread_cond_wait (fifo->notFull, fifo->mutex);
}
queueAdd (fifo, i);
pthread_mutex_unlock (fifo->mutex);
pthread_cond_signal (fifo->notEmpty);
SLEEP (200);
}
return
(NULL);
}
void
* consumer (
void
*q)
{
int
d;
Queue *fifo = (Queue *)q;
for
(
int
i = 0; i < LOOP; i++)
{
// 临界区操作:若队列不空,则取出数据
pthread_mutex_lock (fifo->mutex);
while
(fifo->empty)
{
printf (
"consumer: Queue EMPTY. "
);
pthread_cond_wait (fifo->notEmpty, fifo->mutex);
}
queueDel (fifo, &d);
pthread_mutex_unlock (fifo->mutex);
// 取完数据,发“队列不满”信号
pthread_cond_signal (fifo->notFull);
printf (
"consumer: recieved %d. "
, d);
SLEEP(200);
}
// 与上面类似
for
(
int
i = 0; i < LOOP; i++)
{
pthread_mutex_lock (fifo->mutex);
while
(fifo->empty)
{
printf (
"consumer: Queue EMPTY. "
);
pthread_cond_wait (fifo->notEmpty, fifo->mutex);
}
queueDel (fifo, &d);
pthread_mutex_unlock (fifo->mutex);
pthread_cond_signal (fifo->notFull);
printf (
"consumer: recieved %d. "
, d);
SLEEP (50);
}
return
(NULL);
}
Queue *queueInit (
void
)
{
Queue *q = (Queue *)malloc (
sizeof
(Queue));
if
(q == NULL)
return
(NULL);
q->empty =
true
;
q->full =
false
;
q->head = 0;
q->tail = 0;
q->mutex = (pthread_mutex_t *) malloc (
sizeof
(pthread_mutex_t));
pthread_mutex_init (q->mutex, NULL);
q->notFull = (pthread_cond_t *) malloc (
sizeof
(pthread_cond_t));
pthread_cond_init (q->notFull, NULL);
q->notEmpty = (pthread_cond_t *) malloc (
sizeof
(pthread_cond_t));
pthread_cond_init (q->notEmpty, NULL);
return
(q);
}
void
queueDelete (Queue *q)
{
pthread_mutex_destroy (q->mutex);
free (q->mutex);
pthread_cond_destroy (q->notFull);
free (q->notFull);
pthread_cond_destroy (q->notEmpty);
free (q->notEmpty);
free (q);
}
void
queueAdd (Queue *q,
int
in)
{
q->buf[q->tail] = in;
q->tail++;
if
(q->tail == QUEUE_SIZE)
// 循环队列
q->tail = 0;
if
(q->tail == q->head)
// 添加数据时“触顶”
q->full =
true
;
q->empty =
false
;
return
;
}
void
queueDel (Queue *q,
int
*out)
{
*out = q->buf[q->head];
q->head++;
if
(q->head == QUEUE_SIZE)
// 循环队列
q->head = 0;
if
(q->head == q->tail)
// 取出数据时“触底”
q->empty =
true
;
q->full =
false
;
return
;
}
收藏该网址
版权所有©石家庄振强科技有限公司2024
冀ICP备08103738号-5
网站地图