操作系统之生产者消费者模型

 生产者与消费者模型

代码如下:

参考: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

原文地址:https://www.cnblogs.com/QQ2962269558/p/13368019.html