linux多线程学习(七)——实现“生产者和消费者”

在上一篇文章中,利用信号量实现了线程间的互斥,这一篇将要利用信号量的互斥同步机制来实现一个经典实例,就是“生产者和消费者”。

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; }

从上面的经典例子中,结合了多线程的同时性编程问题。学习线程算是告了一段落,在以后的编程应用中,希望能落实到实践中去,大家一起加油~~

你可能感兴趣的:(linux,多线程编程)