├── 实验二.pdf ├── ex2 ├── b1.exe ├── b2.exe ├── p1.exe ├── p2.exe ├── p1.cpp ├── p2.cpp ├── b2.c ├── b1.c ├── sem.h └── box.h └── README.md /实验二.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Multhree/Linux-interProcessCommunication/HEAD/实验二.pdf -------------------------------------------------------------------------------- /ex2/b1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Multhree/Linux-interProcessCommunication/HEAD/ex2/b1.exe -------------------------------------------------------------------------------- /ex2/b2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Multhree/Linux-interProcessCommunication/HEAD/ex2/b2.exe -------------------------------------------------------------------------------- /ex2/p1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Multhree/Linux-interProcessCommunication/HEAD/ex2/p1.exe -------------------------------------------------------------------------------- /ex2/p2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Multhree/Linux-interProcessCommunication/HEAD/ex2/p2.exe -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 只有代码和报告,具体请看[Linux进程间通信(消息队列/信号量+共享内存)](https://www.cnblogs.com/multhree/p/9124839.html) 2 | 对你有帮助的话点个Star吧ヽ(✿゚▽゚)ノ 3 | -------------------------------------------------------------------------------- /ex2/p1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"sem.h" 3 | #include"box.h" 4 | 5 | 6 | int main() 7 | { 8 | 9 | while(1) 10 | { 11 | int op; 12 | printf("input op:0 send, 1 receive, 2 recall, 3 exit:"); 13 | scanf("%d",&op); 14 | if(op == 0) 15 | { 16 | printf("input msg:"); 17 | int msg; 18 | scanf("%d",&msg); 19 | send(boxB,msg); 20 | } 21 | else if(op == 1) 22 | { 23 | printf("msg:%d\n",receive(boxA)); 24 | } 25 | else if(op == 2) 26 | { 27 | recall(boxB); 28 | } 29 | else if(op == 3) 30 | { 31 | deleteBox(boxA); 32 | break; 33 | } 34 | else 35 | { 36 | printf("invalid op! please input again!\n"); 37 | } 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /ex2/p2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"sem.h" 3 | #include"box.h" 4 | 5 | 6 | int main() 7 | { 8 | 9 | while(1) 10 | { 11 | int op; 12 | printf("input op:0 send, 1 receive, 2 recall, 3 exit:"); 13 | scanf("%d",&op); 14 | if(op == 0) 15 | { 16 | printf("input msg:"); 17 | int msg; 18 | scanf("%d",&msg); 19 | send(boxA,msg); 20 | } 21 | else if(op == 1) 22 | { 23 | printf("msg:%d\n",receive(boxB)); 24 | } 25 | else if(op == 2) 26 | { 27 | recall(boxA); 28 | } 29 | else if(op == 3) 30 | { 31 | deleteBox(boxB); 32 | break; 33 | } 34 | else 35 | { 36 | printf("invalid op! please input again!\n"); 37 | } 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /ex2/b2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define KEY 1234 8 | #define MESSAGEMAXSIZE 1024 9 | #define RECEIVETYPE 0 10 | struct msg 11 | { 12 | long int messageType; 13 | char message[MESSAGEMAXSIZE]; 14 | }; 15 | 16 | int main() 17 | { 18 | struct msg data; 19 | int msgid1 = msgget((key_t)KEY, 0666|IPC_CREAT); 20 | if(msgid1 < 0) 21 | { 22 | printf("msg1get failed.\n"); 23 | exit(EXIT_FAILURE); 24 | } 25 | 26 | 27 | int msgid2= msgget((key_t)(KEY+1), 0666|IPC_CREAT); 28 | if(msgid2 < 0) 29 | { 30 | printf("msg2get failed.\n"); 31 | exit(EXIT_FAILURE); 32 | } 33 | 34 | int op; 35 | while(1) 36 | { 37 | printf("input op:0 send, 1 receive, 2 exit:"); 38 | scanf("%d",&op); 39 | 40 | if(op == 0) 41 | { 42 | printf("input msg:"); 43 | scanf("%s",data.message); 44 | msgsnd(msgid2, &data,MESSAGEMAXSIZE,0); 45 | } 46 | else if(op == 1) 47 | { 48 | msgrcv(msgid1, &data,MESSAGEMAXSIZE,RECEIVETYPE,0); 49 | printf("msg: %s\n",data.message); 50 | } 51 | else if(op == 2) 52 | { 53 | break; 54 | } 55 | else 56 | { 57 | printf("invalid op! please input again!\n"); 58 | } 59 | } 60 | msgctl(msgid1, IPC_RMID, 0); 61 | msgctl(msgid2, IPC_RMID, 0); 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /ex2/b1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define KEY 1234 8 | #define MESSAGEMAXSIZE 1024 9 | #define RECEIVETYPE 0 10 | 11 | struct msg 12 | { 13 | long int messageType; 14 | char message[MESSAGEMAXSIZE]; 15 | }; 16 | 17 | int main() 18 | { 19 | struct msg data; 20 | int msgid1 = msgget((key_t)KEY, 0666|IPC_CREAT);//创建消息队列1 21 | if(msgid1 < 0) 22 | { 23 | printf("msg1get failed.\n"); 24 | exit(EXIT_FAILURE); 25 | } 26 | 27 | 28 | int msgid2= msgget((key_t)(KEY+1), 0666|IPC_CREAT);//创建消息队列2 29 | if(msgid2 < 0) 30 | { 31 | printf("msg2get failed.\n"); 32 | exit(EXIT_FAILURE); 33 | } 34 | 35 | int op; 36 | while(1) 37 | { 38 | printf("input op:0 send, 1 receive, 2 exit:"); 39 | scanf("%d", &op); 40 | 41 | if(op == 0) 42 | { 43 | printf("input msg:"); 44 | scanf("%s",data.message); 45 | msgsnd(msgid1, &data,MESSAGEMAXSIZE,0);//向消息队列1发送消息 46 | } 47 | else if(op == 1) 48 | { 49 | msgrcv(msgid2, &data,MESSAGEMAXSIZE,RECEIVETYPE,0); 50 | printf("msg: %s\n",data.message);//从消息队列2接收消息 51 | } 52 | else if(op == 2) 53 | { 54 | break; 55 | } 56 | else 57 | { 58 | printf("invalid op! please input again!\n"); 59 | } 60 | } 61 | msgctl(msgid1, IPC_RMID, 0); 62 | msgctl(msgid2, IPC_RMID, 0); 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /ex2/sem.h: -------------------------------------------------------------------------------- 1 | #ifndef sem_h 2 | #define sem_h 3 | 4 | #include 5 | #include 6 | 7 | int getNewSem(key_t key)//获取新信号量 8 | { 9 | return semget(key,1,0666|IPC_CREAT); 10 | } 11 | 12 | union semun 13 | { 14 | int val; 15 | struct semid_ds *buf; 16 | unsigned short *arry; 17 | }; 18 | 19 | int setSemValue(int semid,int n)//设置信号量 20 | { 21 | union semun semTemp; 22 | semTemp.val = n; 23 | if(semctl(semid,0,SETVAL,semTemp)==-1) 24 | { 25 | return 0; 26 | } 27 | return 1; 28 | } 29 | 30 | int delSem(int semid)//删除信号量 31 | { 32 | union semun semTemp; 33 | semctl(semid,0,IPC_RMID,semTemp); 34 | } 35 | /* 36 | struct sembuf 37 | { 38 | unsigned short int sem_num; //在信号量集中的序号 39 | short int sem_op; // 对信号量的操作,>0, 0, <0 40 | short int sem_flg; // 操作标识:0, IPC_WAIT, SEM_UNDO 41 | }; 42 | */ 43 | int P(int semid)//P操作 44 | { 45 | struct sembuf semTemp; 46 | semTemp.sem_num = 0; 47 | semTemp.sem_op = -1; 48 | semTemp.sem_flg = SEM_UNDO; 49 | if(semop(semid,&semTemp,1) == -1) 50 | { 51 | printf("P() failed\n"); 52 | return 0; 53 | } 54 | return 1; 55 | } 56 | 57 | int V(int semid)//V操作 58 | { 59 | struct sembuf semTemp; 60 | semTemp.sem_num = 0; 61 | semTemp.sem_op = 1; 62 | semTemp.sem_flg = SEM_UNDO; 63 | if(semop(semid,&semTemp,1) == -1) 64 | { 65 | printf("V() failed\n"); 66 | return 0; 67 | } 68 | return 1; 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /ex2/box.h: -------------------------------------------------------------------------------- 1 | #ifndef box_h 2 | #define box_h 3 | 4 | #include"sem.h" 5 | #include 6 | #include 7 | #include 8 | 9 | #define boxId 1234 10 | #define boxLen 5 11 | 12 | struct box 13 | { 14 | //信箱头 15 | int bid;//信箱标识符 16 | int bsize;//信格总数 17 | /*同步信号量*/ 18 | int mailnum;//与信箱中信件数量相关的信号量 19 | int freenum;//与信箱中空信格数量相关的信号量 20 | /*互斥信号量*/ 21 | int rmutex;//接收信件时的互斥信号量 22 | int wmutex;//存入信件时的互斥信号量 23 | int out;//当前可读取信件的信格地址 24 | int in;//当前可存入信件的信格地址 25 | //信箱体 26 | int *buf; 27 | void *shm; 28 | }; 29 | 30 | struct box* getNewBox(int len,int n)//获取新信箱,len为信格总数,n为唯一邮箱变量 31 | { 32 | int shmid; 33 | struct box* msgbox = (struct box*)malloc(sizeof(struct box)); 34 | shmid = shmget((key_t)(boxId+n),sizeof(int)*len,0666|IPC_CREAT); 35 | msgbox->shm = shmat(shmid,0,0); 36 | msgbox->buf = (int *)(msgbox->shm); 37 | //初始化信格总数 38 | msgbox->bsize = len; 39 | //初始化邮箱标号,为共享信号的标号 40 | msgbox->bid = shmid; 41 | //初始化信号量 42 | msgbox->mailnum = getNewSem((key_t)(shmid+1)); 43 | setSemValue(msgbox->mailnum,0); 44 | 45 | msgbox->freenum = getNewSem((key_t)(shmid+2)); 46 | setSemValue(msgbox->freenum,len); 47 | 48 | msgbox->rmutex = getNewSem((key_t)(shmid+3)); 49 | setSemValue(msgbox->rmutex,1); 50 | 51 | msgbox->wmutex = getNewSem((key_t)(shmid+4)); 52 | setSemValue(msgbox->wmutex,1); 53 | 54 | msgbox->out = 0; 55 | msgbox->in = 0; 56 | 57 | 58 | return msgbox; 59 | } 60 | 61 | void send(struct box* dest,int msg)//发送 62 | { 63 | P(dest->freenum); 64 | P(dest->wmutex); 65 | dest->buf[dest->in] = msg; 66 | dest->in = (dest->in+1)%dest->bsize; 67 | V(dest->wmutex); 68 | V(dest->mailnum); 69 | }; 70 | 71 | 72 | int receive(struct box* addr)//接收 73 | { 74 | int msg; 75 | P(addr->mailnum); 76 | P(addr->rmutex); 77 | msg = addr->buf[addr->out]; 78 | addr->out = (addr->out+1)%addr->bsize; 79 | V(addr->rmutex); 80 | V(addr->freenum); 81 | 82 | return msg; 83 | }; 84 | 85 | void recall(struct box* addr)//撤销 86 | { 87 | P(addr->mailnum); 88 | P(addr->wmutex); 89 | P(addr->rmutex); 90 | addr->in = (addr->in-1)%addr->bsize; 91 | V(addr->rmutex); 92 | V(addr->wmutex); 93 | V(addr->freenum); 94 | }; 95 | void deleteBox(struct box* msgbox)//删除信箱 96 | { 97 | delSem(msgbox->freenum); 98 | delSem(msgbox->mailnum); 99 | delSem(msgbox->rmutex); 100 | delSem(msgbox->wmutex); 101 | shmdt(msgbox->shm); 102 | shmctl(msgbox->bid,IPC_RMID,0); 103 | }; 104 | 105 | struct box* boxA = getNewBox(boxLen,1); 106 | struct box* boxB = getNewBox(boxLen,2); 107 | #endif 108 | --------------------------------------------------------------------------------