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

📄 test13_a.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);void child_write(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2);void child_read(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2, int num);void resource_free(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2);void sig_kill();void sig_pause();int b_kill, b_pause;       /*用于判断进程是否被要求退出或暂停*/struct PInfo *shm_addr3;   /*共享内存3的首地址*/int main(){ int sem_id, shm_id1, shm_id2, shm_id3; char *shm_addr1, *shm_addr2;  /*共享内存1、2的首地址*/ int pid; int i, j; int sta; fun_init(&sem_id, &shm_id1, &shm_id2, &shm_id3, &shm_addr1, &shm_addr2); /*初始化函数,创建信号量和共享内存*/ for(i=0; i<27; i++)     shm_addr1[i] = '\0';               /*将共享内存1的内容初始化成'\0'*/ for(i=0; i<4; i++)     for(j=0; j<27; j++)         shm_addr2[i*27 + j] = '\0';    /*将共享内存2的内容初始化成'\0'*/ if((pid=fork()) == -1)                  /*创建一个写进程*/    {    printf("fork faild !!!\n");    exit(0);   } if(!pid)                                  {    b_kill = 0;    b_pause = 0;    signal(16, sig_kill);               /*定义要求进程退出运行的软中断处理函数*/    signal(17, sig_pause);              /*定义要求进程暂停的软中断处理函数*/    child_write(sem_id, shm_id1, shm_id2, shm_id3, shm_addr1, shm_addr2);    exit(0);                            /*向共享内存1写字母的功能函数*/   } else   {    for(i=1; i<=4; i++)                 /*创建4个读进程*/       {        pid = fork();        switch(pid)              {               case -1:                       printf("fork faild !!!\n");                         exit(0);               case 0 :                       b_kill = 0;                       b_pause = 0;                       signal(16, sig_kill);                       signal(17, sig_pause);                       child_read(sem_id, shm_id1, shm_id2, shm_id3, shm_addr1, shm_addr2, i);                        exit(0);   /*从共享内存1读字母,将其写入共享内存2中各自对应区域*/               default:                         break;              }     }   if(shmdt(shm_addr1) == -1)         /*与共享内存断开*/      printf("shmdt faild !!!\n");   if(shmdt(shm_addr2) == -1)      printf("shmdt faild !!!\n");   exit(0);  }}/*void fun_init(int *psem_id, int *pshm_id1, int *pshm_id2, int *pshm_id3, char ** pshm_addr1, char **pshm_addr2)返回值:无参数: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的首地址返回给调用函数。函数功能:创建一个包含3个信号量的信号量集,并创建3块共享内存。*/void fun_init(int *psem_id, int *pshm_id1, int *pshm_id2, int *pshm_id3, char ** pshm_addr1, char **pshm_addr2){ int sta; union semun sem_v; *psem_id = semget(SEM_KEY, 3, IPC_CREAT|0600); if(*psem_id == -1)   {    printf("semget faild !!!\n");    exit(0);   } *pshm_id1 = shmget(SHM1_KEY, 27, IPC_CREAT|0600); if(*pshm_id1 == -1)   {    printf("shmget 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_id3 = shmget(SHM3_KEY, sizeof(struct PInfo)*5, IPC_CREAT|0600); if(*pshm_id3 == -1)   {    printf("shmget faild !!!\n");    exit(0);   } sem_v.val = 2; sta  = semctl(*psem_id, 0, SETVAL, sem_v); if(sta == -1)   {    printf("semctl faild !!!\n");    exit(0);   } sem_v.val = 4; sta = semctl(*psem_id, 1, SETVAL, sem_v); if(sta == -1)   {    printf("semctl faild !!!\n");    exit(0);   } sem_v.val = 1; sta = semctl(*psem_id, 2, SETVAL, sem_v); if(sta == -1)   {    printf("semctl faild !!!\n");    exit(0);   } *pshm_addr1 = shmat(*pshm_id1, 0, 0); if(!(*pshm_addr1))   {    printf("shmat faild !!!\n");    exit(0);   } *pshm_addr2 = shmat(*pshm_id2, 0, 0); if(!(*pshm_addr2))   {    printf("shmat faild !!!\n");    exit(0);   }  }/*void child_write(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2)返回值:无参数: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的首地址。函数功能:向共享内存1写入26个英文字母,并在写进程结束运行时,调用resource_free()函数,          使写进程与共享内存脱离,并在没有其他进程与共享内存相连时,销毁共享内存与信号量集。*/void child_write(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2){ int sta; int i; struct sembuf sem_b[2]; shm_addr3 = shmat(shm_id3, 0, 0); if(!shm_addr3)   {    printf("shmat faild in child_write() !!!\n");    exit(0);   } srand((int)time(0)); shm_addr3[0].pid = getpid(); shm_addr3[0].pstatus = 'R'; sem_b[0].sem_num = 0; sem_b[0].sem_flg = SEM_UNDO; sem_b[1].sem_num = 2; sem_b[1].sem_flg = SEM_UNDO; for(i=0; i<26; i++)    {     if(b_kill)       {        resource_free(sem_id, shm_id1, shm_id2, shm_id3, shm_addr1, shm_addr2);        exit(0);       }     if(b_pause)        pause();     sem_b[0].sem_op = -2;     sem_b[1].sem_op = -1;     shm_addr3[0].pstatus = 'V';     sta = semop(sem_id, sem_b, 2);     if(sta == -1)       {        printf("semop faild in child_write() !!!\n");        shm_addr3[0].pstatus = 'X';        resource_free(sem_id, shm_id1, shm_id2, shm_id3, shm_addr1, shm_addr2);        exit(0);       }     shm_addr3[0].pstatus = 'R';     shm_addr1[i] = 'a'+i;     sleep(2);     sem_b[0].sem_op = 2;     sem_b[1].sem_op = 1;     sta = semop(sem_id, sem_b, 2);     if(sta == -1)       {        printf("semop faild in child_write() !!!\n");        shm_addr3[0].pstatus = 'X';        resource_free(sem_id, shm_id1, shm_id2, shm_id3, shm_addr1, shm_addr2);        exit(0);       }     sleep(1);    }   shm_addr3[0].pstatus = 'F';   resource_free(sem_id, shm_id1, shm_id2, shm_id3, shm_addr1, shm_addr2);}/*void child_read(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2, int num)返回值:无参数: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的首地址。      num        int型,取值范围{1,2,3,4},用于对读进程的识别函数功能:从共享内存1读取字符,并将其写入共享内存2中各个读进程各自对应的区域。          在读进程结束时,调用resource_free()函数,读进程与共享内存脱离,并在没有其他进程与共享内存相连时,销毁共享内存与信号量集。*/ void child_read(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2, int num){ struct sembuf  sem_b[2]; int sta; int i; shm_addr3 = shmat(shm_id3, 0, 0); if(!shm_addr3)   {    printf("shmat faild in child_read() !!!\n");    exit(0);   } srand(300*num  + (int)time(0)); shm_addr3[num].pid = getpid(); shm_addr3[num].pstatus = 'R'; sem_b[0].sem_num = 0; sem_b[0].sem_flg = SEM_UNDO; sem_b[1].sem_num = 1; sem_b[1].sem_flg = SEM_UNDO; for(i=0; i<26; i++)    {     if(b_kill)       {        resource_free(sem_id, shm_id1, shm_id2, shm_id3, shm_addr1, shm_addr2);        exit(0);       }     if(b_pause)        pause();     sem_b[0].sem_op = -1;     sem_b[1].sem_op = -1;     shm_addr3[num].pstatus = 'V';     sta = semop(sem_id, sem_b, 2);     if(sta == -1)       {        printf("semop faild in child_read()!!!\n");        resource_free(sem_id, shm_id1, shm_id2, shm_id3, shm_addr1, shm_addr2);        shm_addr3[num].pstatus = 'X';        exit(0);       }     shm_addr3[num].pstatus = 'R';     if(shm_addr1[i] != '\0')        shm_addr2[27*(num-1) + i] = shm_addr1[i];     else        i--;     sem_b[0].sem_op = 1;     sem_b[1].sem_op = 1;     sta = semop(sem_id, sem_b, 2);     if(sta == -1)       {        printf("semop faild in child_read()!!!\n");        shm_addr3[num].pstatus = 'X';        resource_free(sem_id, shm_id1, shm_id2, shm_id3, shm_addr1, shm_addr2);        exit(0);       }     sleep((rand()%5)+1);     }  shm_addr3[num].pstatus = 'F';  resource_free(sem_id, shm_id1, shm_id2, shm_id3, shm_addr1, shm_addr2);}/*void resource_free(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2)返回值:无参数: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的首地址。函数功能:在每个读写进程退出时被调用,用于调用进程的与共享内存脱离,若没有其他进程与共享内存相连,则销毁共享内存与信号量集。*/void resource_free(int sem_id, int shm_id1, int shm_id2, int shm_id3, char *shm_addr1, char *shm_addr2){ int k; int sta; struct shmid_ds shm_buf; 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");   }}/*void sig_kill()返回值:无参数: 无函数功能:收到监控程序发来的结束进程运行的信号时,所执行的软中断处理函数。*/void sig_kill(){ int i; b_kill = 1; for(i=0; i<=4; i++)     if(shm_addr3[i].pid == getpid())        break; shm_addr3[i].pstatus = 'X';}/*void sig_pause()返回值:无参数: 无函数功能:收到监控程序发来的暂停进程运行的信号时,所执行的软中断处理函数。*/void sig_pause(){ int i; for(i=0; i<=4; i++)     if(shm_addr3[i].pid == getpid())        break; if(b_pause == 0)   {    b_pause = 1;    shm_addr3[i].pstatus = 'P';   } else   {    b_pause = 0;    shm_addr3[i].pstatus = 'R';   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -