📄 test13_b.c
字号:
#include "test13.h"void fun_init(int *psem_id, int *pshm_id1, int *pshm_id2, int *pshm_id3, char **pshm_addr1, char **pshm_addr2, struct PInfo **pshm_addr3);char inputcmd(int *ppid);int searchpid(char *ch);void fun_show(int sem_id, char *shm_addr1, char *shm_addr2, struct PInfo *shm_addr3);void fun_kill(struct PInfo *shm_addr3, int PID[5], int pid);void fun_pause(struct PInfo *shm_addr3, int PID[5], int pid);void fun_restart(struct PInfo *shm_addr3, int PID[5], int pid);void fun_quit(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2, struct PInfo *shm_addr3);int main(){ int sem_id, shm_id1, shm_id2, shm_id3; char *shm_addr1, *shm_addr2; struct PInfo *shm_addr3; int pid; char ch; int PID[5]; int i, sta; fun_init(&sem_id, &shm_id1, &shm_id2, &shm_id3, &shm_addr1, &shm_addr2, &shm_addr3); for(i=0; i<=4; i++) PID[i] = shm_addr3[i].pid; while(1) { ch = inputcmd(&pid); switch(ch) { case 's': fun_show(sem_id, shm_addr1, shm_addr2, shm_addr3); break; case 'k': fun_kill(shm_addr3, PID, pid); break; case 'p': fun_pause(shm_addr3, PID, pid); break; case 'r': fun_restart(shm_addr3, PID, pid); break; case 'q': fun_quit(sem_id, shm_id1, shm_id2, shm_id3, shm_addr1, shm_addr2, shm_addr3); case 'e': printf("INPUT CMD ERROR !!!\n"); } }}/*char inputcmd(int *ppid)返回值:char型,返回值范围{'s','k','p','r','q','e'},即返回输入命令的首字母。 若输入的命令错误,则返回'e'。参数:ppid int型指针,用于将输入命令所带的参数{w,a,b,c,d}, 通过调用searchpid()转换成int的{0,1,2,3,4},并返回给*ppid。函数功能:接收字符串命令,并进行分析,将所要操作的类型以char型返回,将操作所针对的进程的id 返回给*ppid。*/char inputcmd(int *ppid){ int i,k; char str[80]; char str_array[2][80]; char *ch=" "; char *p; printf("\nInput Cmd:"); str[0] = '\0'; str_array[0][0] = '\0'; str_array[1][0] = '\0'; i=-1; do { i++; scanf("%c", str+i); }while(str[i] != '\n'); str[i] = '\0'; p = strtok(str, ch); if(!p) return 'e'; strcpy(str_array[0], p); i = 0; while(p = strtok(NULL, ch)) { i++; if(i >= 2) return 'e'; strcpy(str_array[i], p); } if(strcmp(str_array[0],"show") == 0) { if(strlen(str_array[1]) == 0) return 's'; else return 'e'; } if(strcmp(str_array[0], "kill") == 0) { k = searchpid(str_array[1]); if(k != -1) { *ppid = k; return 'k'; } else return 'e'; } if(strcmp(str_array[0], "pause") == 0) { k = searchpid(str_array[1]); if(k != -1) { *ppid = k; return 'p'; } else return 'e'; } if(strcmp(str_array[0], "restart") == 0) { k = searchpid(str_array[1]); if(k != -1) { *ppid = k; return 'r'; } else return 'e'; } if(strcmp(str_array[0], "quit") == 0) { if(strlen(str_array[1]) == 0) return 'q'; else return 'e'; } return 'e';}/*int searchpid(char *ch)返回值:int型,返回值范围{-1,0,1,2,3,4}。参数: ch char*型,指向一个字符串,即输入的命令中所带的参数。函数功能:将输入命令中所带的参数{w,a,b,c,d},对应转换成{0,1,2,3,4},若输入错误的参数返回-1。*/int searchpid(char *ch){ int i; char strp[5][2]={"w", "a", "b", "c", "d"}; for(i=0; i<=4; i++) if(strcmp(ch, strp[i]) == 0) return i; return -1;}/*void fun_show(int sem_id, char *shm_addr1, char *shm_addr2, struct PInfo *shm_addr3)返回值:无参数:sem_id int型,信号量集的ID。 shm_addr1 char型指针,指向共享内存1的首地址。 shm_addr2 char型指针,指向共享内存2的首地址。 shm_addr3 struct PInfo型指针,指向共享内存3的首地址。函数功能:将读写进程的ID、当前运行状态、读写进度显示出来,即显示三块共享内存中的内容。*/void fun_show(int sem_id, char *shm_addr1, char *shm_addr2, struct PInfo *shm_addr3){ int sta; struct sembuf sem_b; sem_b.sem_num = 2; sem_b.sem_op = -1; sem_b.sem_flg = SEM_UNDO; sta = semop(sem_id, &sem_b, 1); if(sta == -1) { printf("semop faild !!!\n"); exit(0); } printf("CHILD W (%d,%c): %s\n", shm_addr3[0].pid, shm_addr3[0].pstatus, shm_addr1); sem_b.sem_op = 1; sta = semop(sem_id, &sem_b, 1); if(sta == -1) { printf("semop faild !!!\n"); exit(0); } sem_b.sem_num = 1; sem_b.sem_op = -4; sem_b.sem_flg = SEM_UNDO; sta = semop(sem_id, &sem_b, 1); if(sta == -1) { printf("semop faild !!!\n"); exit(0); } printf("CHILD A (%d,%c): %s\n", shm_addr3[1].pid, shm_addr3[1].pstatus, shm_addr2); printf("CHILD B (%d,%c): %s\n", shm_addr3[2].pid, shm_addr3[2].pstatus, shm_addr2 + 27*1); printf("CHILD C (%d,%c): %s\n", shm_addr3[3].pid, shm_addr3[3].pstatus, shm_addr2 + 27*2); printf("CHILD D (%d,%c): %s\n", shm_addr3[4].pid, shm_addr3[4].pstatus, shm_addr2 + 27*3); sem_b.sem_op = 4; sta = semop(sem_id, &sem_b, 1); if(sta == -1) { printf("semop faild !!!\n"); exit(0); }}/*void fun_kill(struct PInfo *shm_addr3, int PID[5], int pid)返回值:无参数:shm_addr3 struct PInfo型的指针,指向共享内存3的首地址,其中共享内存3中存放各个进程的ID和当前运行状态标志位 PID int型数组,存放各个进程实际的ID。 pid int型变量,取值范围{0,1,2,3,4},用于访问PID数组中的元素。函数功能:向进程号为PID[pid]的进程发送信号,使此进程结束运行。*/void fun_kill(struct PInfo *shm_addr3, int PID[5], int pid){ char pname[5] = {'w', 'a', 'b', 'c', 'd'}; switch(shm_addr3[pid].pstatus) { case 'F': printf("child %c have finished !\n", pname[pid]); return; case 'X': printf("child %c have been killed !\n", pname[pid]); return; case 'V': printf("child %c is waiting semaphore. can not be killed now !\n", pname[pid]); return; default : kill(PID[pid], 16); }}/*void fun_pause(struct PInfo *shm_addr3, int PID[5], int pid)返回值:无参数:shm_addr3 struct PInfo型的指针,指向共享内存3的首地址,其中共享内存3中存放各个进程的ID和当前运行状态标志位 PID int型数组,存放各个进程实际的ID。 pid int型变量,取值范围{0,1,2,3,4},用于访问PID数组中的元素。函数功能:向进程号为PID[pid]的进程发送信号,使此进程暂停。*/void fun_pause(struct PInfo *shm_addr3, int PID[5], int pid){ char pname[5] = {'w', 'a', 'b', 'c', 'd'}; switch(shm_addr3[pid].pstatus) { case 'F': printf("child %c have finished !\n", pname[pid]); return; case 'X': printf("child %c have been killed !\n", pname[pid]); return; case 'P': printf("child %c have been paused !\n", pname[pid]); return; case 'V': printf("child %c is waiting semaphore. can not be paused now !\n", pname[pid]); return; case 'R' : kill(PID[pid], 17); }}/*void fun_restart(struct PInfo *shm_addr3, int PID[5], int pid)返回值:无参数:shm_addr3 struct PInfo型的指针,指向共享内存3的首地址,其中共享内存3中存放各个进程的ID和当前运行状态标志位 PID int型数组,存放各个进程实际的ID。 pid int型变量,取值范围{0,1,2,3,4},用于访问PID数组中的元素。函数功能:向进程号为PID[pid]的进程发送信号,使此进程结束暂停状态,继续运行。*/void fun_restart(struct PInfo *shm_addr3, int PID[5], int pid){ char pname[5] = {'w', 'a', 'b', 'c', 'd'}; switch(shm_addr3[pid].pstatus) { case 'F': printf("child %c have finished !\n", pname[pid]); return; case 'X': printf("child %c have been killed !\n", pname[pid]); return; case 'R': case 'V': printf("child %c is running !\n", pname[pid]); return; case 'P': kill(PID[pid], 17); return; }}/*void fun_quit(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2, struct PInfo *shm_addr3)返回值:无参数:sem_id int型变量,信号量集的ID。 shm_id1 int型变量,共享内存1的ID。 shm_id2 int型变量,共享内存2的ID。 shm_id3 int型变量,共享内存3的ID。 shm_addr1 char型指针,共享内存1的首地址。 shm_addr2 char型指针,共享内存2的首地址。 shm_addr3 struct PInfo型指针,共享内存3的首地址。函数功能:退出监控程序的运行,并使监控程序与共享内存脱离。若没有其他进程与共享内存相连,则销毁共享内存与信号量集。*/void fun_quit(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2, struct PInfo *shm_addr3){ int k; int sta; struct shmid_ds shm_buf; union semun semun_arg; k=0; if(shmdt(shm_addr1) == -1) printf("shmdt faild in resource_free() !!!\n"); sta = shmctl(shm_id1, IPC_STAT, &shm_buf); if(sta == -1) printf("shmctl faild in resource_free() !!!\n"); else { if(shm_buf.shm_nattch == 0) { k++; sta = shmctl(shm_id1, IPC_RMID, 0); if(sta == -1) printf("shmctl faild in resource_free() !!!\n"); } } if(shmdt(shm_addr2) == -1) printf("shmdt faild in resource_free() !!!\n"); sta = shmctl(shm_id2, IPC_STAT, &shm_buf); if(sta == -1) printf("shmctl faild in resource_free() !!!"); else { if(shm_buf.shm_nattch == 0) { k++; sta = shmctl(shm_id2, IPC_RMID, 0); if(sta == -1) printf("shmctl faild in resource_free() !!!\n"); } } if(shmdt(shm_addr3) == -1) printf("shmdt faild in resource_free() !!!\n"); sta = shmctl(shm_id3, IPC_STAT, &shm_buf); if(sta == -1) printf("shmctl faild in resource_free() !!!\n"); else { if(shm_buf.shm_nattch == 0) { k++; sta = shmctl(shm_id3, IPC_RMID, 0); if(sta == -1) printf("shmctl faild in resource_free() !!!\n"); } } if(k == 3) { sta = semctl(sem_id, 3, IPC_RMID, 0); if(sta == -1) printf("semctl faild in resource_free() !!!\n"); } exit(0);}/*void fun_init(int *psem_id, int *pshm_id1, int *pshm_id2, int *pshm_id3, char **pshm_addr1, char **pshm_addr2, struct PInfo **pshm_addr3)返回值:无参数:psem_id, int型指针,用于将创建的信号量集的ID返回给调用函数。 pshm_id1, int型指针,用于将创建的共享内存1的ID返回给调用函数。 pshm_id2, int型指针,用于将创建的共享内存2的ID返回给调用函数。 pshm_id3, int型指针,用于将创建的共享内存3的ID返回给调用函数。 pshm_addr1 char *型指针,用于将共享内存1的首地址返回给调用函数。 pshm_addr2 char *型指针,用于将共享内存2的首地址返回给调用函数。 pshm_addr3 struct PInfo *型指针,用于将共享内存3的首地址返回给调用函数。函数功能:创建一个包含3个信号量的信号量集,并创建3块共享内存。*/void fun_init(int *psem_id, int *pshm_id1, int *pshm_id2, int *pshm_id3, char **pshm_addr1, char **pshm_addr2, struct PInfo **pshm_addr3){ int sta; *psem_id = semget(SEM_KEY, 3, IPC_CREAT|IPC_EXCL|0600); if(*psem_id != -1) { printf("the write/read program is not running !\n"); printf("the monitoring program can not run now !\n"); sta = semctl(*psem_id, 3, IPC_RMID, 0); exit(0); } else { *psem_id = semget(SEM_KEY, 3, IPC_CREAT|0600); if(*psem_id == -1) { printf("semget faild in fun_init() !!!\n"); exit(0); } } *pshm_id1 = shmget(SHM1_KEY, 27, IPC_CREAT|0600); if(*pshm_id1 == -1) { printf("shmget faild !!!\n"); exit(0); } *pshm_addr1 = shmat(*pshm_id1, 0, 0); if(!(*pshm_addr1)) { printf("shmat faild !!!\n"); exit(0); } *pshm_id2 = shmget(SHM2_KEY, 27*4, IPC_CREAT|0600); if(*pshm_id2 == -1) { printf("shmget faild !!!\n"); exit(0); } *pshm_addr2 = shmat(*pshm_id2, 0, 0); if(!(*pshm_addr2)) { printf("shmat faild !!!\n"); exit(0); } *pshm_id3 = shmget(SHM3_KEY, sizeof(struct PInfo)*5, IPC_CREAT|0600); if(*pshm_id3 == -1) { printf("shmget faild !!!\n"); exit(0); } *pshm_addr3 = (struct PInfo *)shmat(*pshm_id3, 0, 0); if(!(*pshm_addr3)) { printf("shmat faild !!!\n"); exit(0); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -