📄 test15_e.c
字号:
#include "test15.h"void fun_init(int *pmsg_id, int *pshm_id, struct PInfo **pshm_addr);char inputcmd(int *ppid);int searchpid(char *ch);void fun_show(struct PInfo *shm_addr);void fun_kill(struct PInfo *shm_addr, int pid);void fun_create(int msg_id, struct PInfo *shm_addr, int pid);void fun_pause(struct PInfo *shm_addr, int pid);void fun_restart(struct PInfo *shm_addr, int pid);void fun_quit(int msg_id, int shm_id, struct PInfo *shm_addr);int main(){ char ch; int pid; int shm_id, msg_id; struct PInfo * shm_addr; fun_init(&msg_id, &shm_id, &shm_addr); /*创建共享内存与消息队列*/ while(1) { ch = inputcmd(&pid); /*接收字符串命令并进行分析*/ switch(ch) { case 's': fun_show(shm_addr); /*显示各个进程的状态*/ break; case 'k': fun_kill(shm_addr, pid); /*杀死一个进程*/ break; case 'c': fun_create(msg_id, shm_addr, pid); /*重新创建一个进程*/ break; case 'p': fun_pause(shm_addr, pid); /*使一个进程暂停运行*/ break; case 'r': fun_restart(shm_addr, pid); /*使一个进程从暂停恢复运行*/ break; case 'q': fun_quit(msg_id, shm_id, shm_addr); /*使监控程序退出运行*/ case 'e': printf("INPUT CMD ERROR !\n"); /*输入了错误的字符串命令*/ } }}/*void fun_init(int *pmsg_id, int *pshm_id, struct PInfo **pshm_addr)返回值:无参数:pmsg_id int型指针,将消息队列的ID返回给变量*pmsg_id。 pshm_id int型指针,将共享内存的ID返回给变量*pshm_id。 pshm_addr struct PInfo型指针,将共享内存的首地址返回给变量*pshm_addr。函数功能:创建共享内存与消息队列,若此时没有其他进程与共享内存相连,则将创建的共享内存销毁,监控程序退出运行。*/void fun_init(int *pmsg_id, int *pshm_id, struct PInfo **pshm_addr){ int sta; struct shmid_ds shm_buf; *pshm_id = shmget(SHM_KEY, sizeof(struct PInfo)*5, IPC_CREAT|0600); if(*pshm_id == -1) /*创建共享内存,并获得其id*/ { printf("shmget faild in fun_init() !!!\n"); exit(0); } sta = shmctl(*pshm_id, IPC_STAT, &shm_buf); if(sta == -1) /*获取共享内存的状态*/ printf("shmctl faild in fun_init() !!!\n"); else { if(shm_buf.shm_nattch == 0) { /*若当前没有进程与共享内存相连,则将刚创建的共享内存销毁,且监控程序退出运行*/ printf("the parallel computing programs are not running !!!\n"); printf("the monitoring program can not run now !!!\n"); sta = shmctl(*pshm_id, IPC_RMID, 0); if(sta == -1) printf("shmctl faild in fun_init() !!!\n"); exit(0); } } *pshm_addr = shmat(*pshm_id, 0, 0); /*监控程序与共享内存相连*/ if(!(*pshm_addr)) { printf("shmat faild in fun_init() !!!\n"); exit(0); } *pmsg_id = msgget(MSG_KEY, IPC_CREAT|0600); /*创建消息队列*/ if(*pmsg_id == -1) { printf("msgget faild in fun_init() !!!\n"); exit(0); }}/*char inputcmd(int *ppid);返回值:char型变量,返回值范围{s,k,c,p,r,q,e},即返回输入命令的首字母。参数: int型指针,取值范围{0,1,2,3,4},即将命令操作所针对的进程返回给变量*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) /*判断输入的是否是show命令*/ { if(strlen(str_array[1]) == 0) /*判断show命令参数是否合法*/ 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],"create") == 0) { k = searchpid(str_array[1]); if(k != -1) { *ppid = k; return 'c'; } 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},参数: char型指针,即指向的字符串。函数功能:将输入命令中的参数字符串,转换成操作针对的进程号{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<5; i++) if(strcmp(ch,strp[i]) == 0) return i; return -1;}/*void fun_show(struct PInfo *shm_addr);返回值:无参数:shm_addr struct PInfo型指针,即共享内存的首地址。函数功能:将求和进程与并行计算的的ID、当前状态显示出来,即显示共享内存中的内容。*/void fun_show(struct PInfo *shm_addr){ int i; long k, result; result = 0; char pname[5] = {'W', 'A', 'B', 'C', 'D'}; for(i=0; i<5; i++) printf("Child %c(%d,%c):%7ld %13ld\n", pname[i], shm_addr[i].pid, shm_addr[i].pstatus, shm_addr[i].num, shm_addr[i].result); for(k=1; k<=shm_addr[0].num; k++) /*提前将最终结果算出,以供验证*/ result += k*k; printf("Result:%ld\n",result);}/*void fun_kill(struct PInfo *shm_addr, int pid);返回值:无参数: shm_addr struct PInfo型指针,指向共享内存的首地址。 pid int型变量,指定操作针对的进程。函数功能:向指定的进程发送信号,使其结束运行。*/void fun_kill(struct PInfo *shm_addr, int pid){ char pname[5] = {'w', 'a', 'b', 'c', 'd'}; switch(shm_addr[pid].pstatus) /*判断进程的当前状态是否允许被杀死*/ { case 'X': printf("child %c have been killed !\n", pname[pid]); return; case 'F': printf("child %c have finished !\n", pname[pid]); return; default : kill(shm_addr[pid].pid, 17); }}/*void fun_create(int msg_id, struct PInfo *shm_addr, int pid)返回值:无参数:msg_id int型变量,即消息队列的ID shm_addr struct PInfo型指针,指向共享内存的首地址。 pid int型变量,指定要创建的进程。函数功能:向消息队列中发送消息,并在消息类型与消息内容中指定要创建的进程。*/void fun_create(int msg_id, struct PInfo *shm_addr, int pid){ int sta; char pname[5] = {'w', 'a', 'b', 'c', 'd'}; struct msgbuf msg; switch(shm_addr[pid].pstatus) { case 'R': case 'P': printf("child %c exist !\n", pname[pid]); return; case 'F': printf("child %c have finished !\n", pname[pid]); return; } if(pid == 0) msg.mtype = 1; else { msg.mtype = 2; switch(pid) { case 1: strcpy(msg.mtext, "1"); break; case 2: strcpy(msg.mtext, "2"); break; case 3: strcpy(msg.mtext, "3"); break; case 4: strcpy(msg.mtext, "4"); } } sta = msgsnd(msg_id, &msg, 2, 0); if(sta == -1) { printf("msgsnd faild in fun_create !!!\n"); exit(0); }}/*void fun_pause(struct PInfo *shm_addr, int pid);返回值:无参数:shm_addr struct PInfo型指针,指向共享内存的首地址。 pid int型变量,指定要暂停的进程。函数功能:向指定的进程发信号,使其暂停运行。*/void fun_pause(struct PInfo *shm_addr, int pid){ char pname[5] = {'w', 'a', 'b', 'c', 'd'}; switch(shm_addr[pid].pstatus) { case 'X': printf("child %c have been killed !\n", pname[pid]); return; case 'F': printf("child %c have finished !\n", pname[pid]); return; case 'P': printf("child %c have been paused !\n", pname[pid]); return; case 'R': kill(shm_addr[pid].pid, 16); }}/*void fun_restart(struct PInfo *shm_addr, int pid);返回值:无参数:shm_addr struct PInfo型指针,指向共享内存的首地址。 pid int型变量,指定要恢复运行的进程。函数功能:向指定的进程发信号,使其恢复运行。*/void fun_restart(struct PInfo *shm_addr, int pid){ char pname[5] = {'w', 'a', 'b', 'c', 'd'}; switch(shm_addr[pid].pstatus) { case 'X': printf("child %c have been killed !\n", pname[pid]); return; case 'F': printf("child %c have finished !\n", pname[pid]); return; case 'R': printf("child %c is running !\n", pname[pid]); return; case 'P': kill(shm_addr[pid].pid, 16); }}/*void fun_quit(int msg_id, int shm_id, struct PInfo *shm_addr);返回值:无参数:msg_id int型变量,消息队列的ID。 shm_id int型变量,共享内存的ID。 shm_addr struct PInfo型指针,指向共享内存的首地址。函数功能:使监控程序退出运行,并与共享内存脱离,销毁消息队列。 当没有其他进程与共享内存相连时,销毁共享内存。 */void fun_quit(int msg_id, int shm_id, struct PInfo *shm_addr){ int sta; struct msgbuf msg; struct shmid_ds shm_buf; msg.mtype = 3; sta = msgsnd(msg_id, &msg, 2, 0); if(sta == -1) printf("msgsnd faild in fun_quit() !!!\n"); if(shmdt(shm_addr) == -1) printf("shmdt faild in fun_quit() !!!\n"); sta = shmctl(shm_id, IPC_STAT, &shm_buf); if(sta == -1) printf("shmctl faild in fun_quit() !!!\n"); else { if(shm_buf.shm_nattch == 0) { sta = shmctl(shm_id, IPC_RMID, 0); if(sta == -1) printf("shmctl faild in fun_quit() !!!\n"); } } sta = msgctl(msg_id, IPC_RMID, 0); if(sta == -1) printf("msgctl faild in fun_quit() !!!\n"); exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -