Linux C:利用两个线程实现生产者消费者模型

在使用线程实现消费者生产者模型前,简单介绍一下线程的概念。

线程是进程的一个实体,对于进程而言,进程是程序资源分配的最小单元,这在之前提及过;而对于线程,它是程序执行的最小单元,即CPU调度和分派的基本单位,它附属于进程,同样也能独立运行。关于资源分配上,线程基本不拥有系统资源,只拥有运行中必不可少的一些资源如程序计数器,栈等。

对于线程同样有互斥和同步问题,互斥是多个线程之间操作同个共享数据时使某个线程操作,而其他的线程阻塞,直到资源解锁才能访问。同步则是令线程间按一定的顺序去运行。下面的模型就是采用同步机制使一个线程作为生产者,向全局字符数组写入数据,而另一个线程作为消费者,从数组中读取数据,通过两个信号量的P、V操作实现两线程的顺序先后,两者间为“先生产再消费”,即同步来实现。

具体实现代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>

#define TEXT_SZ 1024

sem_t sem1;
sem_t sem2;

char text[TEXT_SZ];

void *write(void *text) //生产者数据输入函数
{

    while(1)
    {
        sem_wait(&sem1); //信号量sem1 p操作
        printf("(producer) write some text:");
        if(fgets((char *)text, TEXT_SZ, stdin) == NULL) //写数据到全局数组
        {
            printf("write error!\n");
            exit(1);
        }
        
        if(strncmp((char *)text,"end",3) == 0) //输入end退出线程1
        {
            sem_post(&sem2); //信号量sem2 v操作
            break;
        }

        sem_post(&sem2); //信号量sem2 v操作
    }
}

void *read(void *text) //消费者读取数据函数
{
    while(1)
    {
        sem_wait(&sem2); //信号量sem2 p操作
        printf("(customer)  read  the text:%s\n",(char *)text); //输出读到的数据
        
        if(strncmp((char *)text,"end",3) == 0) //读取到end,退出线程2
        {
            sem_post(&sem1); //信号量sem1 v操作
            break;
        }

        sem_post(&sem1); //信号量sem1 v操作
    }

}

int main()
{
    pthread_t thread1;
    pthread_t thread2;

    int ret1;
    int ret2;

    if(sem_init(&sem1,0,1) == -1) //初始化信号量sem1
    {
        printf("init sem1 error!\n");
        exit(1);
    }


    if(sem_init(&sem2,0,0) == -1) //初始化信号量sem2
    {
        printf("init sem2 error!\n");
        exit(1);
    }

    if(memset(text,0,sizeof(text)) == NULL)
    {
        printf("memset error!\n");
        exit(1);
    }

    ret1 = pthread_create(&thread1,NULL,(void *)write,(void *)text);//创建线程1
    if(ret1 < 0)
    {
        printf("thread1 create error!\n");
        exit(1);
    }

    ret2 = pthread_create(&thread2,NULL,(void *)read,(void *)text);//创建线程2
    if(ret2 < 0)
    {
        printf("thread2 create error!\n");
        exit(1);
    }

    pthread_join(thread1,NULL); //等待线程1退出
    pthread_join(thread2,NULL);//等待线程2退出
    
    if(sem_destroy(&sem1) == -1) //删除信号量sem1
    {
        printf("delete sem1 error!\n");
        exit(1);
    }
    
    if(sem_destroy(&sem2) == -1) //删除信号量sem2
    {
        printf("delete sem2 error!\n");
        exit(1);
    }

    return 0;
}


  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值