在上一篇文章中,利用信号量实现了线程间的互斥,这一篇将要利用信号量的互斥同步机制来实现一个经典实例,就是“生产者和消费者”。
1、简单描述生产者和消费者的问题。
有一个缓冲区和两个线程:生产者和消费者。生产者把产品放入缓冲区,而消费者从缓冲区中拿走。当缓冲区满时,生产者必须等待;另外,当缓冲区空时,消费者必须等待,并且缓冲区不能同时进行生产者和消费者的操作。
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
-
#define FIFO "my_fifo"
-
#define N 10
-
#define return_if_fail(p) if((p) == 0){printf ("[%s]:func error!/n", __func__);return;}
-
-
typedef struct _PrivInfo
-
{
-
sem_t avail;
-
sem_t full;
-
sem_t mutex;
-
char buf_r[255];
-
time_t end_time;
-
int fd;
-
}PrivInfo;
-
-
static void info_init (PrivInfo* thiz);
-
static void info_destroy (PrivInfo* thiz);
-
static void* productor (PrivInfo* thiz);
-
static void* consumer (PrivInfo* thiz);
-
-
int main (int argc, char* argv[])
-
{
-
pthread_t pt_1 = 0;
-
pthread_t pt_2 = 0;
-
int ret = 0;
-
PrivInfo* thiz = NULL;
-
-
thiz = (PrivInfo*) malloc (sizeof (PrivInfo));
-
if (thiz == NULL)
-
{
-
printf ("[%s]: Failed to malloc PrivInfo./n", __func__);
-
return -1;
-
}
-
-
info_init (thiz);
-
-
ret = pthread_create (&pt_1, NULL, (void*)productor, thiz);
-
if (ret != 0)
-
{
-
perror ("pthread_1_create:");
-
}
-
-
ret = pthread_create (&pt_2, NULL, (void*)consumer, thiz);
-
if (ret != 0)
-
{
-
perror ("pthread_2_func:");
-
}
-
-
pthread_join (pt_1, NULL);
-
pthread_join (pt_2, NULL);
-
-
info_destroy (thiz);
-
thiz = NULL;
-
-
return 0;
-
}
-
-
static void info_init (PrivInfo* thiz)
-
{
-
return_if_fail (thiz != NULL);
-
-
thiz->end_time = time(NULL) + 10;
-
-
sem_init (&thiz->avail, 0, N);
-
sem_init (&thiz->full, 0, 0);
-
sem_init (&thiz->mutex, 0, 1);
-
-
if (mkfifo (FIFO, O_CREAT|O_EXCL) && (errno != EEXIST))
-
{
-
printf ("cannot create fifo server./n");
-
}
-
-
printf ("Prepareing for reading bytes.../n");
-
-
memset (thiz->buf_r, 0, sizeof (thiz->buf_r));
-
-
thiz->fd = open (FIFO, O_RDWR|O_NONBLOCK, 0777);
-
if (thiz->fd == -1)
-
{
-
perror ("open FIFO:");
-
info_destroy (thiz);
-
exit (1);
-
}
-
-
return ;
-
}
-
-
static void info_destroy (PrivInfo* thiz)
-
{
-
return_if_fail (thiz != NULL);
-
-
sem_destroy (&thiz->avail);
-
sem_destroy (&thiz->full);
-
sem_destroy (&thiz->mutex);
-
-
free (thiz);
-
thiz = NULL;
-
-
return;
-
}
-
-
static void* productor (PrivInfo* thiz)
-
{
-
return_if_fail (thiz != NULL);
-
-
int ret = 0;
-
-
while (time (NULL) < thiz->end_time)
-
{
-
sem_wait (&thiz->avail);
-
sem_wait (&thiz->mutex);
-
-
if ((ret = write (thiz->fd, "hello", 5)) == -1)
-
{
-
if (errno == EAGAIN)
-
{
-
printf ("The FIFO has not been read, Please try later again./n");
-
}
-
else
-
{
-
printf ("write hello to the FIFO./n");
-
}
-
}
-
-
sem_post (&thiz->full);
-
sem_post (&thiz->mutex);
-
-
sleep (1);
-
}
-
-
return;
-
}
-
-
static void* consumer (PrivInfo* thiz)
-
{
-
return_if_fail (thiz != NULL);
-
-
int ret = 0;
-
-
while (time (NULL) < thiz->end_time)
-
{
-
sem_wait (&thiz->full);
-
sem_wait (&thiz->mutex);
-
-
if ((ret = read(thiz->fd, thiz->buf_r, 255)) > 0)
-
{
-
-
printf ("read %s frm FIFO./n", thiz->buf_r);
-
}
-
else
-
{
-
if (errno == EAGAIN)
-
{
-
printf ("no data yet./n");
-
}
-
}
-
-
sem_post (&thiz->avail);
-
sem_post (&thiz->mutex);
-
-
sleep(1);
-
}
-
-
return;
-
}
从上面的经典例子中,结合了多线程的同时性编程问题。学习线程算是告了一段落,在以后的编程应用中,希望能落实到实践中去,大家一起加油~~