- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <pthread.h>
- #define BUFFER_SIZE 16
- struct prodcons
- {
- int buffer[BUFFER_SIZE];
- pthread_mutex_t lock;
- int readpos,writepos;
- pthread_cond_t notempty;
- pthread_cond_t notfull;
- };
- void init(struct prodcons* b)
- {
- pthread_mutex_init(&b->lock,NULL);
- pthread_cond_init(&b->notempty,NULL);
- pthread_cond_init(&b->notfull,NULL);
- b->readpos = 0;
- b->writepos = 0;
- }
- void put(struct prodcons* b,int data)
- {
- pthread_mutex_lock(&b->lock);
- while((b->writepos +1)%BUFFER_SIZE==b->readpos)
- {
- printf("wait for not full.\n");
- pthread_cond_wait(&b->notfull,&b->lock);
- }
- b->buffer[b->writepos] = data;
- b->writepos++;
- if(b->writepos >= BUFFER_SIZE)b->writepos=0;
- pthread_cond_signal(&b->notempty);
- pthread_mutex_unlock(&b->lock);
- }
- int get(struct prodcons *b)
- {
- int data;
- pthread_mutex_lock(&b->lock);
- while(b->writepos == b->readpos)
- {
- printf("wait for not empty");
- pthread_cond_wait(&b->notempty,&b->lock);
- }
- data = b->buffer[b->readpos];
- b->readpos++;
- if(b->readpos >=BUFFER_SIZE)b->readpos=0;
- pthread_cond_signal(&b->notfull);
- pthread_mutex_unlock(&b->lock);
- return data;
- }
- #define OVER (-1)
- struct prodcons buffer;
- void *producer(void* data)
- {
- int n;
- for(n=0;n<100;n++)
- {
- printf("put---->%d.\n",n);
- put(&buffer,n);
- }
- put(&buffer,OVER);
- printf("producer stopped!\n");
- return NULL;
- }
- void *consumer(void *data)
- {
- int d;
- while(1)
- {
- d = get(&buffer);
- if(d==OVER)break;
- printf(" %d---->get.\n",d);
- }
- printf("consumer stopped!\n");
- return NULL;
- }
- int main(void)
- {
- pthread_t th_a,th_b;
- void *retval;
- init(&buffer);
- pthread_create(&th_a,NULL,producer,0);
- pthread_create(&th_b,NULL,consumer,0);
- pthread_join(th_a,&retval);
- pthread_join(th_b,&retval);
- return 0;
- }
这时一个生产者与消费者的程序,程序实现了生产者与消费者并行运行,并且共用一个缓存区。其中使用到一个互斥锁和信号量来共同控制对缓存区的互斥访问,缓存的状态(空,满)的协调。但是全都在一个文件之中以至于main.c十分臃肿,下面时自己的进行的代码优化
main.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <pthread.h>
- #include "pro_con.h"
- int main(void)
- {
- pthread_t th_a,th_b;
- void *retval;
- fun.init(&buffer);
- pthread_create(&th_a,NULL,fun.producer,0);
- pthread_create(&th_b,NULL,fun.consumer,0);
- pthread_join(th_a,&retval);
- pthread_join(th_b,&retval);
- return 0;
- }
- //------------------Include Files--------------------------------
- #include <stdio.h>
- #include <pthread.h>
- #include "pro_con.h"
- //-------------------------Function Prototype------------------------
- static void c_init(struct prodcons* b); //初始化信号量
- static void c_put(struct prodcons* b,int data); //向缓存中放入数据
- static int c_get(struct prodcons* b);
- static void* c_producer(void* data);
- static void* c_consumer(void* data);
- //---------------------------Variable-----------------------------
- prodcons_fun fun=
- {
- c_init,
- c_put,
- c_get,
- c_producer,
- c_consumer
- };
- struct prodcons buffer;
- /*
- *============Function=======================================
- * Name : init
- * Description : 初始化缓存指针信息
- *============================================================
- */
- static void c_init(struct prodcons* b) //初始化信号量
- {
- pthread_mutex_init(&b->lock,NULL);
- pthread_cond_init(&b->notempty,NULL);
- pthread_cond_init(&b->notfull,NULL);
- b->readpos = 0;
- b->writepos = 0;
- }
- /*
- *============Function========================================
- * Name : put
- * Description :向缓存中放入数据
- *=============================================================
- */
- static void c_put(struct prodcons* b,int data)
- {
- pthread_mutex_lock(&b->lock);
- while((b->writepos + 1)%BUFFER_SIZE==b->readpos)
- {
- printf("wait for not full.\n");
- pthread_cond_wait(&b->notfull,&b->lock);
- }
- b->buffer[b->writepos] = data;
- b->writepos++;
- if(b->writepos >= BUFFER_SIZE)b->writepos=0;
- pthread_cond_signal(&b->notempty);
- pthread_mutex_unlock(&b->lock);
- }
- /*
- *===========Function===========================================
- * Name :get
- * Description :从缓存中获取数据
- *=============================================================
- */
- static int c_get(struct prodcons* b)
- {
- int data;
- pthread_mutex_lock(&b->lock);
- while(b->writepos == b->readpos)
- {
- printf("wait for not empty");
- pthread_cond_wait(&b->notempty,&b->lock);
- }
- data = b->buffer[b->readpos];
- b->readpos++;
- if(b->readpos >= BUFFER_SIZE)b->readpos=0;
- pthread_cond_signal(&b->notfull);
- pthread_mutex_unlock(&b->lock);
- return data;
- }
- /*
- *================Function========================================
- * Name :producer
- * Description :实现一个生产者程序,当生产-1时,程序终止
- *===============================================================
- */
- static void* c_producer(void* data)
- {
- int n;
- for(n=0;n<100;n++)
- {
- printf("put---->%d.\n",n);
- c_put(&buffer,n);
- }
- c_put(&buffer,OVER);
- printf("producer stopped!\n");
- return NULL;
- }
- /*
- *==============Function======================================
- * Name :consumer
- * Description :消费掉缓存中生产出来的数据,当消费-1时,程序终止
- *=================================================================
- */
- static void* c_consumer(void *data)
- {
- int d;
- while(1)
- {
- d = c_get(&buffer);
- if(d==OVER)break;
- printf(" %d---->get.\n",d);
- }
- printf("consumer stopped!\n");
- return NULL;
- }
- //---------------Defines----------------------------------
- #define OVER (-1) //结束标志
- #define BUFFER_SIZE 16 //使用缓存大小
- //--------------Type define-----------------------------------------
- struct prodcons
- {
- int buffer[BUFFER_SIZE]; //缓存申请
- pthread_mutex_t lock; //缓存锁
- int readpos,writepos; //读写的位置指针
- pthread_cond_t notempty; // 不空的信号量
- pthread_cond_t notfull; //不满的信号量
- };
- typedef struct
- {
- void (*init)(struct prodcons* b); //初始化缓存信息
- void (*put)(struct prodcons* b,int data); //向缓存中放入数据
- int (*get)(struct prodcons* b); //从缓存中获得数据
- void* (*producer)(void* data); //
- void* (*consumer)(void* data); //
- }prodcons_fun;
- //-------------Extern----------------------------------------------
- extern prodcons_fun fun;
- extern struct prodcons buffer;
下面主要是讲讲extern关键字与static关键字(来源百度百科),以及在把函数封装在结构体之中。
extern:
extern可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。例如:在main.c中根本没有声明变量fun与buffer,但是确可以直接使用。extern的原理很简单,就是告诉编译器:“你现在编译的文件中,有一个标识符虽然没有在本文件中定义,但是它是在别的文件中定义的全局变量,你要放行!”如extern int a;仅仅是一个变量的声明,其并不是在定义变量a,并未为a分配内存空间。变量a在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。
static:
当用static修饰变量或者函数的时候,这个变量或者函数将变为静态的,变为静态的有下面几个好处:一:静态全局变量不能被其它文件所用;二:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。
最后在prodcons_fun这个结构体中把所有用到的函数都封装了起来,在此要注意这个结构体的成员永远是 init,put,get,producer,consumer,这五个,因此当fun被初始化为c_init,c_put,c_get,c_producer,c_consumer时,最后调用,还是使用 init,put,get,producer,consumer。因为为初始化的过程中,只是把这几个具体实现函数的函数指针(函数入口地址)传递给了 init,put,get,producer,consumer,这些成员。
还要注意的是,在编译时,需要加上 -l pthread,因为pthread不是默认链接的函数库,如果不加,就会出现找不到有关进程的一些相互函数。
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <pthread.h>
- #define BUFFER_SIZE 16
- struct prodcons
- {
- int buffer[BUFFER_SIZE];
- pthread_mutex_t lock;
- int readpos,writepos;
- pthread_cond_t notempty;
- pthread_cond_t notfull;
- };
- void init(struct prodcons* b)
- {
- pthread_mutex_init(&b->lock,NULL);
- pthread_cond_init(&b->notempty,NULL);
- pthread_cond_init(&b->notfull,NULL);
- b->readpos = 0;
- b->writepos = 0;
- }
- void put(struct prodcons* b,int data)
- {
- pthread_mutex_lock(&b->lock);
- while((b->writepos +1)%BUFFER_SIZE==b->readpos)
- {
- printf("wait for not full.\n");
- pthread_cond_wait(&b->notfull,&b->lock);
- }
- b->buffer[b->writepos] = data;
- b->writepos++;
- if(b->writepos >= BUFFER_SIZE)b->writepos=0;
- pthread_cond_signal(&b->notempty);
- pthread_mutex_unlock(&b->lock);
- }
- int get(struct prodcons *b)
- {
- int data;
- pthread_mutex_lock(&b->lock);
- while(b->writepos == b->readpos)
- {
- printf("wait for not empty");
- pthread_cond_wait(&b->notempty,&b->lock);
- }
- data = b->buffer[b->readpos];
- b->readpos++;
- if(b->readpos >=BUFFER_SIZE)b->readpos=0;
- pthread_cond_signal(&b->notfull);
- pthread_mutex_unlock(&b->lock);
- return data;
- }
- #define OVER (-1)
- struct prodcons buffer;
- void *producer(void* data)
- {
- int n;
- for(n=0;n<100;n++)
- {
- printf("put---->%d.\n",n);
- put(&buffer,n);
- }
- put(&buffer,OVER);
- printf("producer stopped!\n");
- return NULL;
- }
- void *consumer(void *data)
- {
- int d;
- while(1)
- {
- d = get(&buffer);
- if(d==OVER)break;
- printf(" %d---->get.\n",d);
- }
- printf("consumer stopped!\n");
- return NULL;
- }
- int main(void)
- {
- pthread_t th_a,th_b;
- void *retval;
- init(&buffer);
- pthread_create(&th_a,NULL,producer,0);
- pthread_create(&th_b,NULL,consumer,0);
- pthread_join(th_a,&retval);
- pthread_join(th_b,&retval);
- return 0;
- }
这时一个生产者与消费者的程序,程序实现了生产者与消费者并行运行,并且共用一个缓存区。其中使用到一个互斥锁和信号量来共同控制对缓存区的互斥访问,缓存的状态(空,满)的协调。但是全都在一个文件之中以至于main.c十分臃肿,下面时自己的进行的代码优化
main.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <pthread.h>
- #include "pro_con.h"
- int main(void)
- {
- pthread_t th_a,th_b;
- void *retval;
- fun.init(&buffer);
- pthread_create(&th_a,NULL,fun.producer,0);
- pthread_create(&th_b,NULL,fun.consumer,0);
- pthread_join(th_a,&retval);
- pthread_join(th_b,&retval);
- return 0;
- }
pro_con.c
- //------------------Include Files--------------------------------
- #include <stdio.h>
- #include <pthread.h>
- #include "pro_con.h"
- //-------------------------Function Prototype------------------------
- static void c_init(struct prodcons* b); //初始化信号量
- static void c_put(struct prodcons* b,int data); //向缓存中放入数据
- static int c_get(struct prodcons* b);
- static void* c_producer(void* data);
- static void* c_consumer(void* data);
- //---------------------------Variable-----------------------------
- prodcons_fun fun=
- {
- c_init,
- c_put,
- c_get,
- c_producer,
- c_consumer
- };
- struct prodcons buffer;
- /*
- *============Function=======================================
- * Name : init
- * Description : 初始化缓存指针信息
- *============================================================
- */
- static void c_init(struct prodcons* b) //初始化信号量
- {
- pthread_mutex_init(&b->lock,NULL);
- pthread_cond_init(&b->notempty,NULL);
- pthread_cond_init(&b->notfull,NULL);
- b->readpos = 0;
- b->writepos = 0;
- }
- /*
- *============Function========================================
- * Name : put
- * Description :向缓存中放入数据
- *=============================================================
- */
- static void c_put(struct prodcons* b,int data)
- {
- pthread_mutex_lock(&b->lock);
- while((b->writepos + 1)%BUFFER_SIZE==b->readpos)
- {
- printf("wait for not full.\n");
- pthread_cond_wait(&b->notfull,&b->lock);
- }
- b->buffer[b->writepos] = data;
- b->writepos++;
- if(b->writepos >= BUFFER_SIZE)b->writepos=0;
- pthread_cond_signal(&b->notempty);
- pthread_mutex_unlock(&b->lock);
- }
- /*
- *===========Function===========================================
- * Name :get
- * Description :从缓存中获取数据
- *=============================================================
- */
- static int c_get(struct prodcons* b)
- {
- int data;
- pthread_mutex_lock(&b->lock);
- while(b->writepos == b->readpos)
- {
- printf("wait for not empty");
- pthread_cond_wait(&b->notempty,&b->lock);
- }
- data = b->buffer[b->readpos];
- b->readpos++;
- if(b->readpos >= BUFFER_SIZE)b->readpos=0;
- pthread_cond_signal(&b->notfull);
- pthread_mutex_unlock(&b->lock);
- return data;
- }
- /*
- *================Function========================================
- * Name :producer
- * Description :实现一个生产者程序,当生产-1时,程序终止
- *===============================================================
- */
- static void* c_producer(void* data)
- {
- int n;
- for(n=0;n<100;n++)
- {
- printf("put---->%d.\n",n);
- c_put(&buffer,n);
- }
- c_put(&buffer,OVER);
- printf("producer stopped!\n");
- return NULL;
- }
- /*
- *==============Function======================================
- * Name :consumer
- * Description :消费掉缓存中生产出来的数据,当消费-1时,程序终止
- *=================================================================
- */
- static void* c_consumer(void *data)
- {
- int d;
- while(1)
- {
- d = c_get(&buffer);
- if(d==OVER)break;
- printf(" %d---->get.\n",d);
- }
- printf("consumer stopped!\n");
- return NULL;
- }
pro_con.h
- //---------------Defines----------------------------------
- #define OVER (-1) //结束标志
- #define BUFFER_SIZE 16 //使用缓存大小
- //--------------Type define-----------------------------------------
- struct prodcons
- {
- int buffer[BUFFER_SIZE]; //缓存申请
- pthread_mutex_t lock; //缓存锁
- int readpos,writepos; //读写的位置指针
- pthread_cond_t notempty; // 不空的信号量
- pthread_cond_t notfull; //不满的信号量
- };
- typedef struct
- {
- void (*init)(struct prodcons* b); //初始化缓存信息
- void (*put)(struct prodcons* b,int data); //向缓存中放入数据
- int (*get)(struct prodcons* b); //从缓存中获得数据
- void* (*producer)(void* data); //
- void* (*consumer)(void* data); //
- }prodcons_fun;
- //-------------Extern----------------------------------------------
- extern prodcons_fun fun;
- extern struct prodcons buffer;
下面主要是讲讲extern关键字与static关键字(来源百度百科),以及在把函数封装在结构体之中。
extern:
extern可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。例如:在main.c中根本没有声明变量fun与buffer,但是确可以直接使用。extern的原理很简单,就是告诉编译器:“你现在编译的文件中,有一个标识符虽然没有在本文件中定义,但是它是在别的文件中定义的全局变量,你要放行!”如extern int a;仅仅是一个变量的声明,其并不是在定义变量a,并未为a分配内存空间。变量a在所有模块中作为一种全局变量只能被定义一次,否则会出现连接错误。
static:
当用static修饰变量或者函数的时候,这个变量或者函数将变为静态的,变为静态的有下面几个好处:一:静态全局变量不能被其它文件所用;二:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。
最后在prodcons_fun这个结构体中把所有用到的函数都封装了起来,在此要注意这个结构体的成员永远是 init,put,get,producer,consumer,这五个,因此当fun被初始化为c_init,c_put,c_get,c_producer,c_consumer时,最后调用,还是使用 init,put,get,producer,consumer。因为为初始化的过程中,只是把这几个具体实现函数的函数指针(函数入口地址)传递给了 init,put,get,producer,consumer,这些成员。
还要注意的是,在编译时,需要加上 -l pthread,因为pthread不是默认链接的函数库,如果不加,就会出现找不到有关进程的一些相互函数。

本文介绍了一个优化后的生产者与消费者程序,通过分离代码至不同文件,并利用结构体封装函数指针的方式,使得代码更加清晰易维护。文章还解释了extern与static关键字的作用。
1510

被折叠的 条评论
为什么被折叠?



