linux 多线程信号量(生产者消费者问题)

  • 生产者消费者问题

这是一个非常经典的多线程题目,题目大意如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,所有生产者和消费者都是异步方式运行的,但它们必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经装满产品且尚未被取走的缓冲区中投放产品。

#include 
#include 
#include 
#include 
#include 
#include 

sem_t sem_product;      // 产品信号量
sem_t sem_space;        // 仓库容量信号量

typedef struct{
    int space;
    int product;
}pd_sp_def;

pd_sp_def pd_sp;

void* pth_consume(void* arg)
{
    char* name = (char*)arg;
    int cnt;

    while (1)
    {
        //对产品个数减一
        sem_wait(&sem_product);
        pd_sp.product--;
        pd_sp.space++;
        printf("consume %s space:%d, product=%d\n",name,pd_sp.space, pd_sp.product);

        //相应的空间加一
        sem_post(&sem_space);
        sem_getvalue(&sem_product, &cnt);
        //printf("Csm Thread %s consume, count:%d\n", name, , cnt);
        sleep(2);   // 每隔2S消费一个产品
    }

    pthread_exit(0);
}

void* pth_product(void* arg)
{
    char* name = (char*)arg;
    int cnt;

    while (1)
    {
        //刚开始空间是5,空间减一
        sem_wait(&sem_space);
        pd_sp.product++;
        pd_sp.space--;
        printf("product %s space:%d, product=%d\n",name,pd_sp.space, pd_sp.product);
        //产品生产加一
        sem_post(&sem_product);
        sem_getvalue(&sem_product, &cnt);
        //printf("pro Thread %s product, count:%d\n", name, cnt);

        sleep(1);   // 每隔1S生产一个产品
    }

    pthread_exit(0);
}

int main()
{
    pthread_t tid1, tid2, tid3, tid4;
    
    int ret;
    pd_sp.space = 5;
    pd_sp.product = 0; 
    // 初始化信号量
    sem_init(&sem_product, 0, 0);   // 初始状态产品个数为0
    sem_init(&sem_space, 0, 5);     // 初始状态仓库空间为5

    ret = pthread_create(&tid1, NULL, pth_product, "A");
    if (0 != ret)
    {
        perror("create pthead error");
        return -1;
    }

    ret = pthread_create(&tid2, NULL, pth_product, "B");
    if (0 != ret)
    {
        perror("create pthead error");
        return -1;
    }

    ret = pthread_create(&tid3, NULL, pth_consume, "C");
    if (0 != ret)
    {
        perror("create pthead error");
        return -1;
    }

    ret = pthread_create(&tid4, NULL, pth_consume, "D");
    if (0 != ret)
    {
        perror("create pthead error");
        return -1;
    }

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    pthread_join(tid3, NULL);
    pthread_join(tid4, NULL);

    // 销毁信号量
    sem_destroy(&sem_product);
    sem_destroy(&sem_space);

    return 0;
}





product B space:4, product=1
consume D space:5, product=0
product A space:4, product=1
consume C space:5, product=0
product B space:4, product=1
product A space:3, product=2
product B space:2, product=3
consume D space:3, product=2
consume C space:4, product=1
product A space:3, product=2
product B space:2, product=3
product A space:1, product=4
consume D space:2, product=3
product B space:1, product=4
consume C space:2, product=3
product A space:1, product=4
product B space:0, product=5
consume D space:1, product=4
product A space:0, product=5
consume C space:1, product=4
product B space:0, product=5

你可能感兴趣的:(linux,C,生产者消费者,信号量,多线程)