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

📄 test13_b.c

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