Linux进程间通讯—旗语

来源:互联网 发布:php调用短信接口代码 编辑:程序博客网 时间:2024/04/27 19:52
/* *生产者/消费者模型 *给定仓库容积(N) *生成者生成的产品入库 *消费者从仓库中取出产品消费 *仓库满了时生产者不能继续生成 *仓库为空时消费者不能继续消费 *对仓库的访问是独占的 * *semBin控制独占访问 *semMax控制仓库满 *semMin控制仓库空 * *生产者消费者 *P(semMax)P(semMin) *P(semBin)P(semBin) *(*product)++(*product)-- *输出产品信息 *V(semBin)V(semBin) *V(semMin)V(semMax) * */ #include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#include <sys/mman.h>#include <semaphore.h>#include <assert.h>#include <signal.h>#definePC_SHM_NAME"/pcshm"#definePC_SEM_NAME_BIN"/pcsembin"#definePC_SEM_NAME_MAX"/pcsemmax"#definePC_SEM_NAME_MIN"/pcsemmin"#define SHM_LENGTH512//共享内存长度#definePRODUCT_MAX30//仓库容积#ifndef FALSE#define FALSE0#endif#ifndef TRUE#defineTRUE1#endifintexitFlag = 0;//退出标志/* * ctrl+c signal */void ctrlcHandle(int signum){exitFlag = 1;}int main(void){int * product;//产品数,指向共享内存int shmFd;//共享内存句柄sem_t * semBin;//二进制旗语,控制仓库唯一性访问sem_t * semMax;//计数旗语,控制产品上限sem_t * semMin;//计数旗语,控制产品下限_Bool isFirst = FALSE;//首次运行?signal(SIGINT, ctrlcHandle);//准备共享内存shmFd = shm_open(PC_SHM_NAME,O_RDWR | O_CREAT | O_EXCL,0666);if( shmFd >= 0 ){//第一次创建isFirst = TRUE;ftruncate(shmFd, SHM_LENGTH);}else{//重新打开shmFd = shm_open(PC_SHM_NAME, O_RDWR, 0666);if(shmFd < 0){perror("shm_open");exit(EXIT_FAILURE);}}//内存映射product = (int *)mmap(NULL,  SHM_LENGTH,  PROT_READ|PROT_WRITE,  MAP_SHARED,  shmFd,  0);if(product == MAP_FAILED){perror("mmap");shm_unlink(PC_SHM_NAME);exit(EXIT_FAILURE);}if(isFirst){//首次创建共享内存,初始化*product = 0;}//打开/创建旗语if(isFirst){semBin = sem_open(PC_SEM_NAME_BIN,O_CREAT, 0666, 1);semMax = sem_open(PC_SEM_NAME_MAX,O_CREAT, 0666, PRODUCT_MAX);semMin = sem_open(PC_SEM_NAME_MIN,O_CREAT, 0666, 0);}else{semBin = sem_open(PC_SEM_NAME_BIN, 0);semMax = sem_open(PC_SEM_NAME_MAX, 0);semMin = sem_open(PC_SEM_NAME_MIN, 0);}if( (semBin == SEM_FAILED) ||(semMax == SEM_FAILED) ||(semMin == SEM_FAILED) ){perror("sem_open");munmap(product, SHM_LENGTH);shm_unlink(PC_SHM_NAME);exit(EXIT_FAILURE);}//主循环while(!exitFlag){#ifdef PRODUCE//生产者//P(MAX)if( sem_wait(semMax) != 0 )continue;//P(BIN)if( sem_wait(semBin) != 0 ){sem_post(semMax);continue;}//生产(*product)++;printf("produce:%d\n", *product);//V(BIN)assert( sem_post(semBin) == 0 );//V(MIN)assert( sem_post(semMin) == 0 );#else//消费者//P(MIN)if( sem_wait(semMin) != 0 )continue;//P(BIN)if( sem_wait(semBin) != 0 ){sem_post(semMin);continue;}//消费(*product)--;printf("consume:%d\n", *product);//V(BIN)assert( sem_post(semBin) == 0 );//V(MAX)assert( sem_post(semMax) == 0 );#endifusleep(100000);}munmap(product, SHM_LENGTH);shm_unlink(PC_SHM_NAME);sem_close(semBin);sem_close(semMin);sem_close(semMax);sem_unlink(PC_SEM_NAME_BIN);sem_unlink(PC_SEM_NAME_MIN);sem_unlink(PC_SEM_NAME_MAX);return 0;}


原创粉丝点击