• 9.经典进程同步问题


    生产者消费者问题

     

     


    读者-写者问题

     

     


    哲学家进餐问题


    哲学家就餐问题讨论

    为防止死锁发生可采取的措施

    •   最多允许4个哲学家同时坐在桌子周围
    •   仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子
    •   给所有哲学家编号,基数号的哲学家必须首先拿左边的筷子,偶数号的哲学          家则反之
    •   为了避免死锁,把哲学家分为三种状态,思考,饥饿,进食,并且一次拿到两只          筷子, 否则不拿

    每个哲学家拿起第一根筷子一定时间后,若拿不到第二根筷子,再放下第一根筷子


      linux下的消费生产商品代码:

      1 #include <semaphore.h>
      2 #include <unistd.h>
      3 #include <sys/types.h>
      4 #include <pthread.h>
      5 
      6 #include <stdlib.h>
      7 #include <stdio.h>
      8 #include <errno.h>
      9 #include <string.h>
     10 
     11 #define ERR_EXIT(m) 
     12         do 
     13         { 
     14                 perror(m); 
     15                 exit(EXIT_FAILURE); 
     16         }while(0)
     17 
     18 #define CONSUMERS_COUNT 2 //消费者人数
     19 #define PRODUCERS_COUNT 2 //生产者人数
     20 #define BUFFSIZE 5
     21 
     22 int g_buffer[BUFFSIZE];//缓冲区数目
     23 
     24 unsigned short in = 0; //放入产品的指针(生产到哪个缓冲区)
     25 unsigned short out = 0;//取出缓冲区指针(在哪个缓冲区消费的)
     26 unsigned short produce_id = 0;
     27 unsigned short consume_id = 0;
     28 
     29 sem_t g_sem_full;   //缓冲区可以生产的产品数 = BUFFSIZE
     30 sem_t g_sem_empty;  //缓冲区可以消费的产品数 = 0
     31 pthread_mutex_t g_mutex;//互斥信号量
     32 
     33 pthread_t g_thread[CONSUMERS_COUNT + PRODUCERS_COUNT];
     34 
     35 void *consume(void *arg)
     36 {
     37     int i;
     38     int num = (int)arg;
     39     while(1)
     40     {
     41         sem_wait(&g_sem_empty);//wait()操作
     42         pthread_mutex_lock(&g_mutex);//互斥锁
     43 
     44         //遍历缓冲区,看看有哪些缓冲区是可以生产消费的
     45         for(i=0;i<BUFFSIZE;i++)
     46         {
     47             printf("%d  缓存区",i);
     48             if(g_buffer[i] == -1)
     49                 printf("%s","为空");
     50             else
     51                 printf("%d",g_buffer[i]);
     52 
     53             if(i==out)
     54                 printf("	------消费");
     55 
     56             printf("
    ");
     57         }
     58 
     59         //produce()操作(生产产品)
     60         consume_id = g_buffer[out];
     61         printf("%d 开始生产 产品 %d
    ",num,consume_id);
     62         g_buffer[out] = -1;
     63         //将取出缓存区的指针偏移1(下个生产的位置)
     64         out = (out+1) % BUFFSIZE;
     65         printf("%d 生产商品 %d 结束",num,consume_id);
     66         pthread_mutex_unlock(&g_mutex);
     67         sem_post(&g_sem_full);//signal()操作
     68         sleep(1);
     69     }
     70     return NULL;
     71 
     72 }
     73 
     74 void *produce(void *arg)
     75 {
     76     int num = (int)arg;
     77     int i;
     78     while(1)
     79     {
     80         sem_wait(&g_sem_full);
     81         pthread_mutex_lock(&g_mutex);
     82 
     83         //遍历缓冲区,看看有哪些缓冲区是可以生产产品的
     84         for(i=0;i<BUFFSIZE;i++)
     85         {
     86             printf("%d  缓存区",i);
     87             if(g_buffer[i] == -1)
     88             {
     89 
     90                 printf("%s","为空");
     91             }
     92             else
     93                 printf("%d",g_buffer[i]);
     94 
     95             if(i==in)
     96                 printf("	------生产");
     97 
     98             printf("
    ");
     99         }
    100 
    101         printf("%d 开始生产产品 %d
    ",num,produce_id);
    102         g_buffer[in] = produce_id;
    103         in = (in+1)%BUFFSIZE;
    104         printf("%d 产品结束生产 %d
    ",num,produce_id++);
    105         pthread_mutex_unlock(&g_mutex);
    106         sem_post(&g_sem_empty);
    107         sleep(5);
    108     }
    109     return NULL;
    110 }
    111 
    112 int main()
    113 {
    114     int i;
    115     for(i=0;i<BUFFSIZE;i++)
    116         g_buffer[i] = -1;
    117 
    118     sem_init(&g_sem_full,0,BUFFSIZE);
    119     sem_init(&g_sem_empty,0,0);
    120 
    121     pthread_mutex_init(&g_mutex,NULL);
    122 
    123     for(i=0;i<CONSUMERS_COUNT;i++)
    124         pthread_create(&g_thread[i],NULL,consume,(void *)i);
    125 
    126     for(i=0;i<CONSUMERS_COUNT;i++)
    127         pthread_create(&g_thread[i],NULL,produce,(void *)i);
    128 
    129     for(i=0;i<CONSUMERS_COUNT;i++)
    130         pthread_join(g_thread[i],NULL);
    131 
    132     sem_destroy(&g_sem_full);
    133     sem_destroy(&g_sem_empty);
    134     sem_destroy(&g_mutex);
    135 
    136     return 0;
    137 
    138 }
    View Code

     linux下哲学家进餐代码

     1 #include <pthread.h>
     2 #include <stdio.h>
     3 #include <stdlib.h>
     4 
     5 
     6 #define N 5
     7 #define LEFT (i+N-1)%N
     8 #define RIGHT (i+1)%N
     9 #define THINK_TIME 3
    10 #define EAT_TIME 2
    11 
    12 enum { THINKING, HUNGRY, EATING } state[N];
    13 
    14 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER, s[N];
    15 
    16 //如果能吃法就吃饭
    17 void test(int i)
    18 {
    19     if (state[i] == HUNGRY
    20      && state[LEFT] != EATING
    21      && state[RIGHT] != EATING)
    22     {
    23         state[i] = EATING;
    24         pthread_mutex_unlock(&s[i]);//哲学家饱了
    25     }
    26 }
    27 
    28 //第i个哲学家饿了
    29 void take_forks(int i)
    30 {
    31     pthread_mutex_lock(&mutex);
    32     state[i] = HUNGRY;
    33     test(i);
    34     pthread_mutex_unlock(&mutex);
    35     pthread_mutex_lock(&s[i]);//等待哲学家饿了
    36 }
    37 
    38 //第i个哲学家思考
    39 void put_forks(int i)
    40 {
    41     pthread_mutex_lock(&mutex);
    42     state[i] = THINKING;
    43     test(LEFT);
    44     test(RIGHT);
    45     pthread_mutex_unlock(&mutex);
    46 }
    47 
    48 void think(int i)
    49 {
    50     printf("philosopher %d is thinking...
    ", i);
    51     sleep(THINK_TIME);
    52 }
    53 
    54 void eat(int i)
    55 {
    56     printf("philosopher %d is eating...
    ", i);
    57     sleep(EAT_TIME);
    58 }
    59 
    60 //线程函数
    61 void* phi(void* vargp)
    62 {
    63     int i = *(int*)vargp;
    64     while (1)
    65     {
    66         think(i);
    67         take_forks(i);
    68         eat(i);
    69         put_forks(i);
    70     }
    71     return NULL;
    72 }
    73 
    74 int main()
    75 {
    76     int i;
    77     pthread_t tid[N];
    78     for (i = 0; i < N; i++)
    79         pthread_create(&tid[i], NULL, phi, (void*)(&i));
    80     for (i = 0; i < N; i++)
    81         pthread_join(tid[i], NULL);
    82     return 0;
    83 }
    View Code

    注意编译时候后面要加上 -lpthread

     

  • 相关阅读:
    java 缓存框架java caching system使用示例
    2020牛客寒假算法集训营2
    VJ train1 O统计问题 题解
    ACM#学习心得0
    2020牛客寒假集训营1
    高精度加减乘除
    VJ train1 I彼岸
    VC编译常见错误
    EVC开发MapXMobile 环境搭建
    用Evc+Pocket PC 2003 开发MapxMobie
  • 原文地址:https://www.cnblogs.com/xiaochi/p/8029636.html
Copyright © 2020-2023  润新知