进程间通信之信号量semaphore--linux内核剖析( 八 )
示例程序调用semctl函数设置信号量的值程序#include #include #include
#include #include #include
通过semctl实现PV操作的函数库#include #include #include #include union semun{intval;struct semid_ds*buf;unsigned short*array;};// 将信号量sem_id设置为init_valueint init_sem(int sem_id, int init_value){union semunsem_union;sem_union.val = init_value;if (semctl(sem_id, 0, SETVAL, sem_union) == -1){perror("Sem init");exit(1);}return 0;}// 删除sem_id信号量int del_sem(int sem_id){union semun sem_union;if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1){perror("Sem delete");exit(1);}return 0;}// 对sem_id执行p操作int sem_p(int sem_id){struct sembufsem_buf;sem_buf.sem_num = 0;//信号量编号sem_buf.sem_op= -1;//P操作sem_buf.sem_flg = SEM_UNDO;//系统退出前未释放信号量 , 系统自动释放if (semop(sem_id,exit(1);}return 0;}// 对sem_id执行V操作int sem_v(int sem_id){struct sembufsem_buf;sem_buf.sem_num = 0;sem_buf.sem_op= 1;//V操作sem_buf.sem_flg = SEM_UNDO;if (semop(sem_id,exit(1);}return 0;}
#include #include #include #include static int nsems;static int semflg;static int semid;int errno=0;union semun {int val;struct semid_ds *buf;unsigned short *array;}arg;int main(){struct sembuf sops[2]; //要用到两个信号量 , 所以要定义两个操作数组int rslt;unsigned short argarray[80];arg.array = argarray;semid = semget(IPC_PRIVATE, 2, 0666);if(semid < 0 ){printf("semget failed. errno: %d\n", errno);exit(0);}//获取0th信号量的原始值rslt = semctl(semid, 0, GETVAL);printf("val = %d\n",rslt);//初始化0th信号量 , 然后再读取 , 检查初始化有没有成功arg.val = 1; // 同一时间只允许一个占有者semctl(semid, 0, SETVAL, arg);rslt = semctl(semid, 0, GETVAL);printf("val = %d\n",rslt);sops[0].sem_num = 0;sops[0].sem_op = -1;sops[0].sem_flg = 0;sops[1].sem_num = 1;sops[1].sem_op = 1;sops[1].sem_flg = 0;rslt=semop(semid, sops, 1); //申请0th信号量 , 尝试锁定if (rslt < 0 ){printf("semop failed. errno: %d\n", errno);exit(0);}//可以在这里对资源进行锁定sops[0].sem_op = 1;semop(semid, sops, 1); //释放0th信号量rslt = semctl(semid, 0, GETVAL);printf("val = %d\n",rslt);rslt=semctl(semid, 0, GETALL, arg);if (rslt < 0){printf("semctl failed. errno: %d\n", errno);exit(0);}printf("val1:%d val2: %d\n",(unsigned int)argarray[0],(unsigned int)argarray[1]);if(semctl(semid, 1, IPC_RMID) == -1){perror(“semctl failure while clearing reason”);}return(0);}
信号量的牛刀小试——生产者与消费者问题1.问题描述: 有一个长度为N的缓冲池为生产者和消费者所共有 , 只要缓冲池未满 , 生产者便可将 消息送入缓冲池;只要缓冲池未空 , 消费者便可从缓冲池中取走一个消息 。 生产者往缓冲池 放信息的时候 , 消费者不可操作缓冲池 , 反之亦然 。
2.使用多线程和信号量解决该经典问题的互斥
#include #include #include #include #include #define BUFF_SIZE 10char buffer[BUFF_SIZE];char count;//缓冲池里的信息数目sem_t sem_mutex;//生产者和消费者的互斥锁sem_t p_sem_mutex;//空的时候 , 对消费者不可进sem_t c_sem_mutex;//满的时候 , 对生产者不可进void * Producer(){while(1){sem_wait(//当缓冲池未满时sem_wait(//等待缓冲池空闲count++;sem_post(if(count < BUFF_SIZE)//缓冲池未满{sem_post(}if(count > 0)//缓冲池不为空{sem_post(}}}void * Consumer(){while(1){sem_wait( //缓冲池未空时sem_wait(//等待缓冲池空闲count--;sem_post(if(count > 0){sem_post(}}return NULL;}int main(){pthread_t ptid,ctid;//initialize the semaphores//sem_init(//sem_init(//creating producer and consumer threadsif(pthread_create(exit(1);}if(pthread_create(exit(1);}if(pthread_join(ptid, NULL)) /* wait for the producer to finish */{printf("\n ERROR joining thread");exit(1);}if(pthread_join(ctid, NULL)) /* wait for consumer to finish */{printf("\n ERROR joining thread");exit(1);}//sem_destroy(//sem_destroy(//exit the main threadpthread_exit(NULL);return EXIT_SUCCESS;}
- 通气会|12月4~6日,2020中国信息通信大会将在成都举行
- 中国|浅谈5G移动通信技术的前世和今生
- 星期一|亚马逊:黑五与网络星期一期间 第三方卖家销售额达到48亿美元
- 建设|龙元建设中标中国移动宁波信息通信产业园二期施工项目
- IPO|三旺通信IPO:产品结构相对单一业务规模较小 研发人员占员工总数33%
- 空间|垃圾文件正在吞噬你的C盘空间用这四种方法,还你一个干净的C盘
- 广告点击|广告效果评估:30天的广告时间评估最全面
- 要来|折叠屏iPhone终于要来了!可惜发布的时间有点晚,你愿意等吗?
- 智能手机品|越南手机悄然崛起!创立短短2年时间,在当地接连击退苹果、小米
- 科技|短视频行业领先 云想科技成长空间广阔