⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test15_e.c

📁 进程间调度
💻 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 + -