• 简单的生产-消费者程序


     1 #include <stdlib.h>
     2 #include <pthread.h>
     3 #include <stdio.h>
     4 #include <sys/unistd.h>
     5 
     6 #define PRINT_LINE  printf("FILE: %s,  LINE: %d
    ", __FILE__, __LINE__);
     7 #define CYCLE_TIME  (5)
     8 typedef struct msg {
     9     struct msg *prev;
    10     struct msg *next;
    11     int num;
    12 } *pMsg;
    13 
    14 pMsg head;
    15 pMsg tail;
    16 pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
    17 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
    18 void printList();
    19 void *consumer(void *p)
    20 {
    21     struct msg *mp = NULL;
    22     for (;;) {
    23     pthread_mutex_lock(&lock);
    24     while (head == NULL && tail == NULL) {
    25         printf("head is: %p, tail is: %p
    ", head, tail);
    26         pthread_cond_wait(&has_product, &lock);
    27     }
    28     //printList();
    29     mp = tail;
    30     //if tail point the first Node, tail->next is NULL, and tail->prev is also NULL!
    31     //So, in this condition, tail point to NULL after statement "tail = tail->prev;"
    32     //this happened before second node is produced, because consumer get the lock
    33     tail = tail->prev;
    34     if (tail) {//tail not point to first
    35         tail->next = NULL;
    36     }
    37     else //tail point to first, so after consume node, List is EMPTY!
    38         head = NULL;//init List to NULL, so producer will add the next node to 
    39                     //List and arise tail to it, add consumer will wait until List is Not EMPTY.
    40     pthread_mutex_unlock(&lock);
    41     printf("Consume	%d
    ", mp->num);
    42     free(mp);        //PRINT_LINE
    43     sleep(rand() % CYCLE_TIME);
    44     }
    45 }
    46 
    47 void *producer(void *p)
    48 {
    49     struct msg *mp;
    50     for (;;) {
    51     mp = malloc(sizeof(struct msg));
    52     mp->num = rand() % 1000 + 1;
    53     printf("Produce	%d
    ", mp->num);
    54     pthread_mutex_lock(&lock);
    55     mp->prev = NULL;
    56     mp->next = head;
    57     if (tail == NULL) {    //if the first Node is consumed
    58         //before the second node is produced,
    59         //this statement arise tail to second node.
    60         tail = mp;
    61     }
    62     if (head)
    63         head->prev = mp;
    64     head = mp;
    65     //printList();
    66     pthread_mutex_unlock(&lock);
    67     pthread_cond_signal(&has_product);
    68 
    69     sleep(rand() % CYCLE_TIME);
    70     }
    71 }
    72 
    73 int main(int argc, char *argv[])
    74 {
    75     head = tail = NULL;
    76     pthread_t pid, cid;
    77     srand(time(NULL));
    78     pthread_create(&pid, NULL, producer, NULL);
    79     pthread_create(&cid, NULL, consumer, NULL);
    80     pthread_join(pid, NULL);
    81     pthread_join(cid, NULL);
    82     return 0;
    83 }
    84 
    85 void printList()
    86 {
    87     pMsg mp=NULL;
    88     printf("------------List Start ----------
    ");
    89     mp = head;
    90     while (mp) {
    91     printf
    92         ("element: mp - %p, mp->prev - %p, mp->num - %d, mp->next - %p;
    ",
    93          mp, mp->prev, mp->num, mp->next);
    94     printf("head: %p, tail: %p
    ", head, tail);
    95     mp = mp->next;
    96     }
    97     printf("------------List End ----------
    ");
    98 }

    参考的<<Linux C 一站式编程>> "第35章 线程 第3节 线程同步"的代码和习题

  • 相关阅读:
    20220528 08:00:01
    208. Implement Trie (Prefix Tree) (Rust version)
    【mq】从零开始实现 mq12消息的批量发送与回执
    【mq】从零开始实现 mq08配置优化 fluent
    【mq】从零开始实现 mq13注册鉴权 auth
    【mq】从零开始实现 mq10消费者拉取消息回执 pull message ack
    【mq】从零开始实现 mq09消费者拉取消息 pull message
    【mq】从零开始实现 mq11消费者消息回执添加分组信息 pull message ack groupName
    学习随笔
    算法随笔
  • 原文地址:https://www.cnblogs.com/freudshow/p/5159389.html
Copyright © 2020-2023  润新知