生产者与消费者模型
代码如下:
参考: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操作