#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include <time.h>
#include <windows.h>
struct data //信号量结构体
{
    sem_t empty; //记录空缓冲区个数
    sem_t full; //记录装满数据缓冲区个数
    int buffer; //缓冲区
};
pthread_mutex_t mutex; //互斥锁
int num = 0; //记录缓冲区数据的个数
struct data sem;
void* Producer(void *arg)
{
    while(1)
    {
        Sleep(rand()%100); //随机睡眠
        sem_wait(&sem.empty);//信号量的 P 操作
        pthread_mutex_lock(&mutex);//互斥锁上锁
        num++;
        printf("Producer 生产了一条数据:%d\n 输入数据:", num);
        scanf("%d", &sem.buffer);
        pthread_mutex_unlock(&mutex);//互斥锁解锁
        sem_post(&sem.full);//信号量的 V 操作
    }
}
void* Consumer(void *arg)
{
    while(1)
    {
        Sleep(rand()%100); //随机睡眠
        sem_wait(&sem.full);//信号量的 P 操作
        pthread_mutex_lock(&mutex);//互斥锁上锁
        num--;
        printf("Consumer 消费了一条数据: %d\n", num);
        printf("消费数据: %d\n", sem.buffer);
        pthread_mutex_unlock(&mutex);//互斥锁解锁
        sem_post(&sem.empty);//信号量的 V 操作
    }
}
int main()
{
    sem_init(&sem.empty, 0, 1); //信号量初始化
    sem_init(&sem.full, 0, 0);
    pthread_mutex_init(&mutex, NULL); //互斥锁初始化
    pthread_t producid;
    pthread_t consumid;
    pthread_create(&producid, NULL, Producer, NULL); //创建生产者线程
    pthread_create(&consumid, NULL, Consumer, NULL); //创建消费者线程
    pthread_join(consumid, NULL); //线程等待,如果没有这一步,主程序会直接结束,导致线程也直接退出。
    sem_destroy(&sem.empty); //信号量的销毁
    sem_destroy(&sem.full);
    pthread_mutex_destroy(&mutex); //互斥锁的销毁
    return 0;
}

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#define TRUE 1
#define FALSE 0
#define SIZE 10
typedef int QueueData;
typedef struct _queue //队列结构体
{
    int data[SIZE];
    int front; // 指向队头的下标
    int rear; // 指向队尾的下标
} Queue;
struct data //信号量结构体
{
    sem_t empty; //记录空缓冲区个数
    sem_t full; //记录装满数据缓冲区个数
    Queue q; //缓冲仓库:队列
};
pthread_mutex_t mutex; //互斥锁
struct data sem;
int num=0;
int InitQueue (Queue *q) // 队列初始化
{
    if (q == NULL)
    {
        return FALSE;
    }
    q->front = 0;
    q->rear = 0;
    return TRUE;
}
int QueueEmpty (Queue *q) //判断空对情况
{
    //完善程序;
    if((q->front==q->rear)) return true;
    else return false;
}
int QueueFull (Queue *q) //判断队满的情况
{
    //完善程序;
    if((q->rear+1)%SIZE==q->front) return true;
    else return false;
}
int DeQueue (Queue *q, int *x) //出队函数
{
    //完善程序;
    if(QueueEmpty(q)) return false;
    int tmp=0;
    tmp=q->data[q->front];
    x=&tmp;
    q->front=(q->front+1)%SIZE;
    return *x;
}
int EnQueue (Queue *q, int x) //进队函数
{
    //完善程序;
    if(QueueFull(q)) return false;
    q->data[q->rear]=x;
    q->rear=(q->rear+1)%SIZE;
    return true;
}
void* Producer(void *arg)
{
    while(1)
    {
        Sleep(rand()%100); //随机睡眠
        sem_wait(&sem.empty);//信号量的 P 操作
        pthread_mutex_lock(&mutex);//互斥锁上锁
        num++;
        printf("Producer 生产了一条数据:%d\n 输入数据:", num);
        int tmp;
        scanf("%d",&tmp);
        EnQueue(&sem.q,tmp);
        pthread_mutex_unlock(&mutex);//互斥锁解锁
        sem_post(&sem.full);//信号量的 V 操作
    }
}
void* Consumer(void *arg)
{
    while(1)
    {
        Sleep(rand()%10000); //随机睡眠
        sem_wait(&sem.full);//信号量的 P 操作
        pthread_mutex_lock(&mutex);//互斥锁上锁
        num--;
        printf("Consumer 消费了一条数据: %d\n", num);
        int tmp;
        tmp = DeQueue(&sem.q,&tmp);
        printf("消费数据: %d\n", tmp);

        pthread_mutex_unlock(&mutex);//互斥锁解锁
        sem_post(&sem.empty);//信号量的 V 操作
    }
}
int main()
{
    sem_init(&sem.empty, 0, 10);//信号量初始化(做多容纳 10 条消息,容纳了 10 条生产者将不会生产消息)
    sem_init(&sem.full, 0, 0);
    pthread_mutex_init(&mutex, NULL); //互斥锁初始化
    InitQueue(&(sem.q)); //队列初始化
    pthread_t producid;
    pthread_t consumid;
    pthread_create(&producid, NULL, Producer, NULL); //创建生产者线程
    pthread_create(&consumid, NULL, Consumer, NULL); //创建消费者线程
    pthread_join(consumid, NULL); //线程等待,如果没有这一步,主程序会直接结束,导致线程也直接退出。
    sem_destroy(&sem.empty); //信号量的销毁
    sem_destroy(&sem.full);
    pthread_mutex_destroy(&mutex); //互斥锁的销毁
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <pthread.h>
#include <errno.h>
#include <math.h>
#include <windows.h>
//筷子作为mutex
pthread_mutex_t chopstick[6] ;
void *eat_think(void *arg)
{
    char phi = *(char *)arg;
    int left,right; //左右筷子的编号
    switch (phi)
    {
    case 'A':
        left = 5;
        right = 1;
        break;
    case 'B':
        left = 1;
        right = 2;
        break;
    case 'C':
        left = 2;
        right = 3;
        break;
    case 'D':
        left = 3;
        right = 4;
        break;
    case 'E':
        left = 4;
        right = 5;
        break;
    }
//int i;
    for(;;)
    {
        Sleep(rand()%1000); //思考
        pthread_mutex_lock(&chopstick[left]);
        pthread_mutex_lock(&chopstick[right]);
        //补充拿起左右筷子的程序段
        printf("Philosopher %c is eating.\n",phi);
        Sleep(rand()%1000); //吃饭
        pthread_mutex_unlock(&chopstick[left]); //放下左手的筷子
        printf("Philosopher %c release chopstick %d\n", phi, left);
        pthread_mutex_unlock(&chopstick[right]); //放下右手的筷子
        printf("Philosopher %c release chopstick %d\n", phi, right);
    }
}
int main()
{
    pthread_t A,B,C,D,E; //5个哲学家
    char p1,p2,p3,p4,p5;
    p1='A';
    p2='B';
    p3='C';
    p4='D';
    p5='E';
    int i;
    for (i = 0; i < 5; i++)
        pthread_mutex_init(&chopstick[i],NULL);
    pthread_create(&A,NULL, eat_think, &p1);
    pthread_create(&B,NULL, eat_think, &p2);
    pthread_create(&C,NULL, eat_think, &p3);
    pthread_create(&D,NULL, eat_think, &p4);
    pthread_create(&E,NULL, eat_think, &p5);
    pthread_join(A,NULL);
    pthread_join(B,NULL);
    pthread_join(C,NULL);
    pthread_join(D,NULL);
    pthread_join(E,NULL);
    return 0;
}