【转】linux C 解决 生产者消费者问题
2010-10-27 19:55
225 查看
#include<linux/init.h> #include<linux/module.h> #include<linux/wait.h> #include<linux/sem.h> #include<linux/sched.h> #define BUFF_SIZE 10 /*仓库中有十个位置可以存放产品*/ /* * _PRODUCE: 标识生产者的状态: * RUNNING: 生产中 * STOPPED: 停止生产 */ typedef enum _PRODUCE{RUNNING,STOPPED}PRODUCE; /* * _storage: 产品存放地 * buff : 仓库 * lock: 仓库门锁,一个时间只能允许生产者存放产品或者只允许消费者消费产品 * amount: 产品现有的个数 * state: 生产者的生产状态 * (*wait): 锁定仓库门 * (*signal): 开启仓库门 */ struct _storage { char buff[BUFF_SIZE][20]; struct semaphore lock; int amount; PRODUCE state; void (*wait)(struct semaphore *lock); void (*signal)(struct semaphore *lock); }; /* * procon_lock: 产品数量检查锁 * (*wait): 等待有产品可以消费或者是等待仓库有位置可以放产品 * (*signla): 消费产品或者存放产品返回 */ struct procon_lock { struct _storage *storage; void (*wait)(struct _storage *storage); void (*signal)(struct _storage *storage); }; /* * _lock: 打包各种资源 * *storage: 仓库资源 * *empty: 等待仓库有位置可以存放产品 * *full: 等待仓库里有产品可以消费 */ struct _lock { struct _storage *storage; struct procon_lock *empty; struct procon_lock *full; }; void empty_wait(struct _storage *storage); void empty_signal(struct _storage *storage); void full_wait(struct _storage *storage); void full_signal(struct _storage *storage); int producer(void *p); int consumer(void *p); /* * storage: 仓库 */ struct _storage storage = { .amount=0, /*初始仓库中没有产品*/ .state=RUNNING, .wait=down, .signal=up, }; /* * empty: 等待仓库有位置方产品锁 */ struct procon_lock empty = { .storage=&storage, .wait=empty_wait, .signal=empty_signal, }; /* * full: 等待仓库有产品可以消费锁 */ struct procon_lock full = { .storage=&storage, .wait=full_wait, .signal=full_signal, }; /* * lock: 打包资源,将其传递给生产者和消费者 */ struct _lock lock = { .storage = &storage, .empty = &empty, .full = &full }; MODULE_LICENSE("Dual BSD/GPL"); /* * procon_init: 内核模块初始化函数 */ static int procon_init(void) { printk(KERN_INFO"Resolving the proceducer-consumer problem/n"); memset(storage.buff,'/0',BUFF_SIZE*20);/*清空仓库*/ init_MUTEX(&storage.lock); /*打开仓库门*/ //kernel_thread(producer,&lock,CLONE_KERNEL); //kernel_thread(producer,&lock,CLONE_KERNEL); kernel_thread(producer,&lock,CLONE_KERNEL); /*启动生产线,生产者开始生产产品*/ kernel_thread(consumer,&lock,CLONE_KERNEL);/*消费者开始消费产品*/ //kernel_thread(consumer,&lock,CLONE_KERNEL); return 0; } /* * procon_exit: 内核模块卸载函数 */ static void procon_exit(void) { printk(KERN_INFO"Resolved the proceducer-consumer problem/n"); } /* * producer: 生产者,负责生产二十个产品 * @*p: 生产需要的资源 */ int producer(void *p) { struct _lock *lock=(struct _lock *)p; /*解包资源*/ struct _storage *storage=lock->storage;/*获取仓库资源*/ struct procon_lock *empty=lock->empty;/*获取仓库位置探测资源*/ struct procon_lock *full=lock->full;/*获取仓库位置探测资源*/ struct task_struct *task=current;/*取得当前线程描述符*/ int i,j; printk(KERN_INFO"%d:producer start produce products.../n",task->pid);/*显示开始生产*/ for(i=0;i<20;i++) { /*总共生产二十个产品*/ empty->wait(empty->storage); /*如果仓库已经放满,则等待直到有位置可以放产品*/ storage->wait(&storage->lock);/*打开仓库门*/ for(j=0;j<BUFF_SIZE;j++) { /*寻找一个可以放产品的位置*/ if(!strlen(storage->buff[j])) break; } snprintf(storage->buff[j],20,"%d:product-%d",task->pid,i);/*生产产品,放入仓库*/ printk(KERN_INFO"%d:producer produce %s/n",task->pid,storage->buff[j]);/*生产者提示已经生产*/ full->signal(full->storage);/*提示消费者有产品可以消费*/ storage->signal(&storage->lock);/*关闭仓库门*/ } storage->state=STOPPED;/*生产完毕,关闭生产线*/ printk(KERN_INFO"%d:producer exit.../n",task->pid); /*退出生产*/ return 0; } /* * consumer: 消费者,如果有产品,则消费产品 * @*p: 消费需要的资源 */ int consumer(void *p) { struct _lock *lock=(struct _lock *)p; struct _storage *storage=lock->storage; struct procon_lock *empty=lock->empty; struct procon_lock *full=lock->full; struct task_struct *task=current; int i; printk(KERN_INFO"%d:consumer start consume products.../n",task->pid);/*提示开始消费*/ for(;;) { /*如果仓库中已经没有产品并且生产者已经退出生产线,则停止消费*/ if(storage->amount==0&&storage->state==STOPPED){ break; } full->wait(full->storage); /*如果仓库门没有产品,则等待直到有产品*/ storage->wait(&storage->lock);/*打开仓库门*/ for(i=0;i<BUFF_SIZE;i++) {/*寻找一个产品*/ if(strlen(storage->buff[i])) break; } printk(KERN_INFO"%d:consumer consume %s/n",task->pid,storage->buff[i]);/*消费者提示获得了产品*/ memset(storage->buff[i],'/0',20);/*消费产品*/ empty->signal(empty->storage);/*告诉生产者仓库有位置可以放产品*/ storage->signal(&storage->lock); /*关闭仓库门*/ } printk(KERN_INFO"%d:consumer exit.../n",task->pid); return 0; } /* * empty_wait: 等待仓库中有位置可以放产品 * @storage: 仓库 */ void empty_wait(struct _storage *storage) { do { if(storage->amount<BUFF_SIZE) /*如果仓库中有位置可以放产品,则退出等待*/ break; schedule();/*等待仓库中有空位置*/ }while(1); } /* * empty_signal: 通知生产者者仓库中有位置可以放产品 * @*storage: 仓库 */ void empty_signal(struct _storage *storage) { storage->amount--; /*产品计数减一*/ } /* * full_wait: 等待仓库中有产品可以消费 * @*storage: 仓库 */ void full_wait(struct _storage *storage) { do { if(storage->amount>0) /*如果仓库中有产品可以消费,则返回*/ break; schedule();/*等待有产品*/ }while(1); } /* * full_signal: 通知消费者仓库中有产品可以消费 * @*storage: 仓库 */ void full_signal(struct _storage *storage) { storage->amount++; /*产品计数加一*/ } module_init(procon_init); module_exit(procon_exit); MODULE_AUTHOR("Niu Tao"); MODULE_DESCRIPTION("The proceducer-consumer problem"); MODULE_ALIAS("a simplest module");
Makefile:
obj-m :=procon.o CURRENT_PATH := $(shell pwd) LINUX_KERNEL := $(shell uname -r) LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL) all: make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions Module.symvers .Makefile.swp
程序运行结果:
[13899.280451] Resolving the proceducer-consumer problem [13899.284977] 16104:producer start produce products... [13899.284984] 16104:producer produce 16104:product-0 [13899.284987] 16104:producer produce 16104:product-1 [13899.284990] 16104:producer produce 16104:product-2 [13899.284992] 16104:producer produce 16104:product-3 [13899.284994] 16104:producer produce 16104:product-4 [13899.284997] 16104:producer produce 16104:product-5 [13899.284999] 16104:producer produce 16104:product-6 [13899.285002] 16104:producer produce 16104:product-7 [13899.285004] 16104:producer produce 16104:product-8 [13899.285007] 16104:producer produce 16104:product-9 [13899.339264] 16105:consumer start consume products... [13899.339495] 16105:consumer consume 16104:product-0 [13899.339633] 16104:producer produce 16104:product-10 [13899.339769] 16105:consumer consume 16104:product-10 [13899.339907] 16104:producer produce 16104:product-11 [13899.340042] 16105:consumer consume 16104:product-11 [13899.340208] 16104:producer produce 16104:product-12 [13899.340344] 16105:consumer consume 16104:product-12 [13899.340481] 16104:producer produce 16104:product-13 [13899.340616] 16105:consumer consume 16104:product-13 [13899.340887] 16104:producer produce 16104:product-14 [13899.341036] 16105:consumer consume 16104:product-14 [13899.341175] 16104:producer produce 16104:product-15 [13899.341310] 16105:consumer consume 16104:product-15 [13899.341447] 16104:producer produce 16104:product-16 [13899.341582] 16105:consumer consume 16104:product-16 [13899.341719] 16104:producer produce 16104:product-17 [13899.341854] 16105:consumer consume 16104:product-17 [13899.342029] 16104:producer produce 16104:product-18 [13899.342164] 16105:consumer consume 16104:product-18 [13899.342302] 16104:producer produce 16104:product-19 [13899.342305] 16104:producer exit... [13899.342525] 16105:consumer consume 16104:product-19 [13899.342663] 16105:consumer consume 16104:product-1 [13899.342808] 16105:consumer consume 16104:product-2 [13899.343060] 16105:consumer consume 16104:product-3 [13899.343214] 16105:consumer consume 16104:product-4 [13899.343352] 16105:consumer consume 16104:product-5 [13899.343489] 16105:consumer consume 16104:product-6 [13899.343625] 16105:consumer consume 16104:product-7 [13899.343762] 16105:consumer consume 16104:product-8 [13899.343899] 16105:consumer consume 16104:product-9 [13899.343902] 16105:consumer exit... [14598.468929] Resolved the proceducer-consumer problem
原文出自:
http://blog.chinaunix.net/u2/73528/showart_1269939.html
相关文章推荐
- 【读书笔记】linux系统用semaphore来解决经典的生产者-消费者问题
- Linux多线程实践(8) --Posix条件变量解决生产者消费者问题
- Linux多线程实践(8) --Posix条件变量解决生产者消费者问题
- Linux多线程实践(8) --Posix条件变量解决生产者消费者问题
- Linux下用环形buf以及POSIX版本信号量解决生产者消费者问题
- linux下生产者与消费者问题代码,以及编译c代码时error:undefined reference to sem_wait 解决方法之一
- 分别在windows和linux下用信号量解决生产者消费者问题
- Linux多线程实践(5) --Posix信号量与互斥量解决生产者消费者问题
- 信号量解决生产者,消费者问题
- 生产者-消费者问题实现 (linux下C语言)
- Linux 系统应用编程——多线程经典问题(生产者-消费者)
- java信号量PV操作 解决生产者-消费者问题
- 1,使用信号量解决生产者-消费者问题
- 互斥锁加条件变量解决生产者消费者问题
- java 生产者消费者问题 并发问题的解决(转)
- c#多线程之生产者与消费者问题的解决
- Linux组件封装之五:生产者消费者问题
- 使用POSIX线程解决“生产者/消费者”问题
- 信号量解决生产者-消费者问题
- 生产者与消费者问题(linux下C实现)