zoukankan      html  css  js  c++  java
  • 操作系统之生产者消费者模型

     生产者与消费者模型

    代码如下:

    参考:https://saucer-man.com/backend_development/19.html

     1 #include <stdio.h>  
     2 #include <pthread.h>  
     3 #include<semaphore.h>
     4 
     5 sem_t empty,full;                //定义全局同步信号量empty,full
     6 pthread_mutex_t mutex;          //定义一个全局互斥量,在不同函数中  
     7 int buffer_count=0;             //定义一个全局变量,表示管道内得产品数目  
     8   
     9 void *producer( void *arg );    //生产者线程  
    10 void *consumer( void *arg );    //消费者线程  
    11   
    12 int main(int argc , char *argv[]){  
    13     pthread_t thrd_prod , thrd_cons;  
    14   
    15     pthread_mutex_init( &mutex , NULL );    //初始化互斥量  
    16       sem_init (&empty, 0, 5);            //初始化empty信号量
    17     sem_init (&full, 0, 0);            //初始化full信号量
    18     //创建生产者和消费者线程  
    19     if( pthread_create( &thrd_prod , NULL, producer ,  
    20                 NULL ) != 0 )  
    21         printf( "thread create failed." ); 
    22   
    23     if( pthread_create( &thrd_cons , NULL, consumer ,  
    24                 NULL ) != 0 )  
    25         printf( "thread create failed." );  
    26   
    27     //等待线程结束  
    28     if( pthread_join( thrd_prod , NULL ) != 0 )  
    29         printf( " wait thread failed.");  
    30     if( pthread_join( thrd_cons , NULL ) != 0 )  
    31         printf( " wait thread failed.");  
    32       sem_destroy (&full);               //释放同步量
    33       sem_destroy(&empty);            //释放同步量
    34     pthread_mutex_destroy( &mutex );        //关闭互斥量  
    35     return 0;  
    36 }  
    37   
    38 void *producer( void *arg){  
    39     while(1){  
    40         sem_wait(&empty);  //empty-1 
    41         pthread_mutex_lock( &mutex );   //加锁  
    42         //成功占有互斥量,接下来可以对缓冲区(仓库)进行生产  
    43         //操作  
    44         printf( " producer put a product to buffer."); 
    45         buffer_count++;
    46         printf("the buffer_count is %d
    ",buffer_count) ;  
    47         pthread_mutex_unlock( &mutex ); //解锁
    48         sem_post(&full);          //full+1 
    49     }  
    50 }  
    51 void *consumer( void *arg ){  
    52     while(1)
    53         {
    54         sem_wait(&full); //full-1
    55         pthread_mutex_lock( &mutex );   //加锁  
    56         //成功占有互斥量,接下来可以对缓冲区(仓库)进行取出  
    57         //操作  
    58         printf( " consumer get a product from buffer.");  
    59           buffer_count--;
    60         printf("the buffer_count is %d
    ",buffer_count) ;
    61         pthread_mutex_unlock( &mutex ); //解锁  
    62         sem_post(&empty);        //empty+1 
    63       }
    64 }

    创建线程函数

    pthread_create( &thrd_prod , NULL, producer , NULL );

    线程创建成功时,返回0;否则返回错误编号。

    第一个参数为指向线程标识符的指针。

    第二个参数用来设置线程属性。

    第三个参数是线程运行函数的起始地址。

    最后一个参数是运行函数的参数。

    信号量初始化函数

    sem_init (&empty, 0, 5);            //初始化empty信号量

    信号量的数据类型为结构sem_t,它本质上是一个长整型的数。函数sem_init()用来初始化一个信号量。它的原型为:  

    extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));  

    sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;value给出了信号量的初始值。 

    线程等待函数

    pthread_join( thrd_prod , NULL );

    用于等待线程thrd_prod结束。

    等待线程结束函数

    pthread_mutex_init( &mutex , NULL );

    以动态方式创建互斥锁,第二个参数指定了新建互斥锁的属性。

    如果第二个参数为NULL,则使用默认的互斥锁属性,默认属性为快速互斥锁 。

    返回0表示成功。

    利用PV操作实现进程之间的互斥

     P(mutex)

    pthread_mutex_lock( &mutex );   //加锁  

    V(mutex)

    pthread_mutex_unlock( &mutex ); //解锁  

     

    利用PV操作实现进程之间的同步

    P操作

    sem_wait(&empty);  //empty-1

    函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。

    函数sem_trywait ( sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。

    V操作

    sem_post(&full);          //full+1  

    函数sem_post( sem_t *sem )用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。

     

    参考

    linux下C语言实现生产者消费者问题

    https://saucer-man.com/backend_development/19.html

    pthread_create函数的详细讲解(包括向线程函数传递参数详解)

    https://blog.csdn.net/liangxanhai/article/details/7767430

    pthread_join用法解释

    https://blog.csdn.net/danelumax2/article/details/24191411

    互斥锁 pthread_mutex_init()函数

    https://blog.csdn.net/yasi_xi/article/details/19112077

    sem_init,sem_post,sem_wait 信号量的用法解释

    https://blog.csdn.net/allens_zhou/article/details/40425375

    PV操作

    https://zhuanlan.zhihu.com/p/61326272

  • 相关阅读:
    16 Errors and Exceptions
    13 Asynchronous Programming
    wpf入门
    iframe cross domain
    ini_set("error_log",$error_path)设置
    MySQL中merge表存储引擎用法
    php中静态属性静态方法的用法
    PHP的SESSIONID生成原理
    composer的基本 使用
    相邻省份数组
  • 原文地址:https://www.cnblogs.com/QQ2962269558/p/13368019.html
Copyright © 2011-2022 走看看