新网 网站建立,手机建立一个免费网站,wordpress怎么运行,网站首页设计风格信号灯集#xff08;信号量数组#xff09;#xff1a;1、实现进程同步的机制#xff1b;2、在一个信号灯集中#xff0c;可以有很多信号灯#xff1b;3、这些信号灯集中的信号灯相互独立#xff0c;每个灯的值的改变都不会影响到其他的信号灯#xff1b;4、信号灯的值…信号灯集信号量数组1、实现进程同步的机制2、在一个信号灯集中可以有很多信号灯3、这些信号灯集中的信号灯相互独立每个灯的值的改变都不会影响到其他的信号灯4、信号灯的值一般设置为二值量即0或者1其中0代表没有资源1代表有资源常用的接口函数一、创建一个信号灯集semget函数 #include sys/sem.hint semget(key_t key, int nsems, int semflg);/*参数key键值IPC_PRIVATE keynsems信号灯集合中信号灯的个数semflag创建的标志位IPC_CREAT|0666 或 IPC_CREAT|IPC_EXCL|0666返回值成功 semid失败 -1 重置错误码*/二、控制信号灯集semctl函数 #include sys/sem.hint semctl(int semid, int semnum, int cmd, ...);/*参数semid信号灯集的IDsenum:信号灯的编号 从0开始cmd:命令码SETVAL设置信号灯的值 ---第四个参数val选项GETVAL获取信号灯的值 ---不需要第四个参数IPC_STAT获取信号灯集的属性---第四个参数buf选项IPC_SET 设置信号灯集的属性---第四个参数buf选项IPC_RMID第二参数被忽略第4个参数不用填写 ...:可变参返回值成功GETVAL成功返回信号灯的值其余的命令码成功返回0失败 -1 重置错误码*/union semun{int val; /* Value for SETVAL */struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */};三、操作信号灯集中信号灯semop函数 #include sys/sem.hint semop(int semid, struct sembuf *sops, size_t nsops);/*参数semid信号灯集的编号sops操作方式struct sembuf{unsigned short sem_num; //信号灯的编号short sem_op; //操作方式PV-1:P操作申请资源 1:V操作释放资源short sem_flg; //操作的标志位 0阻塞 IPC_NOWAIT非阻塞方式操作}nsops本次操作信号灯的个数返回值成功 0失败 -1 重置错误码*/自定义封装信号灯集函数自定义头文件 #ifndef __SEM_H__#define __SEM_H__int sem_init(int nsems); //信号灯集中信号灯的个数int sem_wait_P(int semid,int sem_num);//信号灯集的编号信号灯的编号int sem_post_V(int semid,int sem_num);int sem_exit(int semid);#endif源码文件 #include stdio.h#include stdlib.h#include string.h#include sys/types.h#include sys/ipc.h#include sys/sem.h#include sys/shm.h#include unistd.h#include sem.h#include errno.hunion semun {int val; //设置信号灯的值struct semid_ds *buf; //信号灯集的属性};/*struct sembuf{unsigned short sem_num; //信号灯的编号short sem_op; //操作方式PV-1:P操作申请资源 1:V操作释放资源short sem_flg; //操作的标志位 0阻塞 IPC_NOWAIT非阻塞方式操作}*/int sem_init(int nsems) //信号灯集中信号灯的个数{int semid 0;key_t key ftok(/home/linux/work, K);if(-1 key){perror(ftok error);exit(-1);}//创建信号灯集/*当使用IPC_EXCL选项时如果共享资源已经存在则创建操作将失败并返回-1。这个选项主要用于确保在创建共享资源时不会发生冲突。*/if(-1 (semid semget(key,nsems,IPC_CREAT|IPC_EXCL|0666))) {if(EEXIST errno){if(-1 (semid semget(key,nsems,IPC_CREAT|0666))){perror(semget error);exit(-1);}return semid;}else{perror(semget error);exit(-1);}}//初始化信号灯集union semun myval {.val 1};if(-1 semctl(semid,0,SETVAL,myval)){perror(semctl error);exit(-1);}myval.val 0;for(int i 1; i nsems; i){if(-1 semctl(semid,i,SETVAL,myval)){perror(semctl error);exit(-1);}}return semid;}//获取资源int sem_wait_P(int semid,int sem_num)//信号灯集的编号信号灯的编号{struct sembuf mysem;mysem.sem_num sem_num;mysem.sem_op -1;mysem.sem_flg 0;if(-1 semop(semid,mysem,1)){perror(semop error);exit(-1);}}//释放资源int sem_post_V(int semid,int sem_num){struct sembuf mysem;mysem.sem_num sem_num;mysem.sem_op 1;mysem.sem_flg 0;if(-1 semop(semid,mysem,1)){perror(semop error);exit(-1);}}//销毁信号灯集int sem_exit(int semid){if(-1 semctl(semid,0,IPC_RMID)){perror(semctl error);exit(-1);}}
使用信号灯集实现共享内存的同步写端 #include stdio.h#include stdlib.h#include string.h#include sys/types.h#include sys/ipc.h#include sys/sem.h#include sys/shm.h#include unistd.h#include sem.h#include errno.h#define PIGE_SIZE 4*1024int main(int argc, char const *argv[]){key_t key ftok(/home/linux/work, K);if(-1 key){perror(ftok error);exit(-1);}//创建共享内存int shmid shmget(key,2*PIGE_SIZE,IPC_CREAT|0666);if(-1 shmid){perror(shmget error);exit(-1);}//映射共享内存char *k_addr shmat(shmid,NULL,0);if((void *)-1 k_addr){perror(shmat error);exit(-1);}//创建信号灯集int semid sem_init(2);//向共享内存中写入数据while(1){sem_wait_P(semid,0); //申请0号灯资源fgets(k_addr,128,stdin);k_addr[strlen(k_addr)-1] \0;sem_post_V(semid,1); //释放1号灯资源if(!strncmp(k_addr,exit,4)){break;}}//取消映射if(-1 shmdt(k_addr)){perror(shmdt error);exit(-1);}//删除共享内存if(-1 shmctl(shmid,IPC_RMID,NULL)){perror(shmctl error);exit(-1);}//销毁信号灯集sem_exit(semid);return 0;}
读端 #include stdio.h#include stdlib.h#include string.h#include sys/types.h#include sys/ipc.h#include sys/sem.h#include sys/shm.h#include unistd.h#include sem.h#include errno.h#define PIGE_SIZE 4*1024int main(int argc, char const *argv[]){key_t key ftok(/home/linux/work, K);if(-1 key){perror(ftok error);exit(-1);}//创建共享内存int shmid shmget(key,2*PIGE_SIZE,IPC_CREAT|0666);if(-1 shmid){perror(shmget error);exit(-1);}//映射共享内存char *k_addr shmat(shmid,NULL,0);if((void *)-1 k_addr){perror(shmat error);exit(-1);}//创建信号灯集int semid sem_init(2);while(1){sem_wait_P(semid,1);printf([%s]\n,k_addr);if(!strcmp(k_addr,exit)){break;}sem_post_V(semid,0);}//取消映射if(-1 shmdt(k_addr)){perror(shmdt error);exit(-1);}//删除共享内存if(-1 shmctl(shmid,IPC_RMID,NULL)){perror(shmctl error);exit(-1);}//销毁信号灯集sem_exit(semid);return 0;}
运行结果 linuxubuntu:~/work/MSG/SME$ ./whellohiI Love Chinalinuxubuntu:~/work/MSG/SME$ ./r[hello][hi][I Love China]