📄 ipc.c
字号:
/* 用关IPC的程序 */#include <stdio.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include <sys/shm.h>#include <sys/msg.h>#include <sys/wait.h>#include <signal.h>#define PROCESS_BUF_SIZE 20/** @Purpose: 这个函数用于在不同的操作系统下返回正确的IPC名字,Posix IPC要求 以斜杠开头的字符串,但在Digital Unix上试图使用此字符串做为一个 文件创建 @Parameter: @return: IPC名字,存放此结果字符串的内存空间是动态分配的,调用者可以通过 free释放 @Author @Date**///char * px_ipc_name(const char *name)//{ // char *dir,*dst,*slash; // if((dst=malloc(PATH_MAX))==NULL) // return NULL; /* 可以使用环境变量覆盖默认目录 */// if((dir=getenv("PX_IPC_NAME"))==NULL) { //#ifdef POSIX_IPC_PREFIX// dir=POSIX_IPC_PREFIX;//#else// dir="/tmp/";//#endif // } /* dir 必须以一个斜杠结束 */// slash=(dir[strlen(dir)-1]=='/')?"":"/"); /* 不使用sprintf()是因为它不检查目标缓冲区是否溢出,snprintf的第二参数为 目标缓冲区的大小 */// snprintf(dst,PATH_MAX,"%s%s%s",dir,slash,name);// return(dst); //} int waitcount=0;int intrcount=0; /** 这是一个多进程协作工作的模拟程序 */void PrintText(){ printf("\n---------------------------------------\n"); printf("\n1 Start multiProcess instance"); printf("\n2 Terminal a MultiProcess "); printf("\nq Exit console "); printf("\n---------------------------------------\n"); printf("Please choice:");}void pro_sigchld(int signo){ pid_t pid1; char Msg[255]; int stat; while((pid1=waitpid(-1,&stat,WNOHANG))>0) { waitcount++; sprintf(Msg,"\nwaitpid() call: child %d terminated !",pid1); write(1,Msg,strlen(Msg)); } return; }void pro_sigchld_2(int signo){ pid_t pid1; char Msg[255]; char ExitSatus[255]; long i; int stat; while((pid1=wait(&stat))>0) { /*if ((pid1=wait(&stat))>0) {*/ if (WIFEXITED(stat)) sprintf(ExitSatus,"Normal Exit !exitcode=%d",(int)WEXITSTATUS(stat)); if (WIFSIGNALED(stat)) sprintf(ExitSatus,"Unable capture signal Exit !signalcode=%d",(int)WTERMSIG(stat)); if (WIFSTOPPED(stat)) sprintf(ExitSatus,"Stop process Exit !signalcode=%d",(int)WSTOPSIG(stat)); waitcount++; sprintf(Msg,"\nwait() call: Child %d terminated ! %s",pid1,ExitSatus); write(1,Msg,strlen(Msg)); //for(i=1;i<100000000;i++); //sleep(3); } return; }int MultiProcess(){ char cCommand; int i; struct sigaction sa_old,sa_new; sigset_t pendset,maskset; /* 建立进程间通信所需的资源 */ pid_t ChildSet[PROCESS_BUF_SIZE],tmp_pid; int ChldNum=0; /* 它们会被多个进程共享 */ int semid; /* 信号量集的 IPC ID */ int shmid; /* 共享内存的 IPC ID */ int msgid; /* 消息队列的 IPC ID */ /*union semun arg1={1,NULL,NULL};*/ /* 设置信号处理程序 */ sa_new.sa_handler=pro_sigchld_2; sigemptyset(&sa_new.sa_mask); //sigaddset(&sa_new.sa_mask,SIGCHLD); sa_new.sa_flags=0; //sa_new.sa_flags=SA_NOMASK; //sa_new.sa_flags=SA_NODEFER; //sa_new.sa_flags=SA_NOCLDSTOP; sigaddset(&sa_new.sa_mask,SIGCHLD); if(sigaction(SIGCHLD,&sa_new,&sa_old)==-1) { perror("sigaction()"); exit(1); } /* 申请信号量集 资源 */ if((semid=semget(IPC_PRIVATE,2,0660))==-1) { perror("semget()"); exit(1); } /* 设置信号量集中的一个信号量为二值信号量 */ /** arg1.val=1; semctl(semid,1,SETVAL,arg1); arg1.val=2; semctl(semid,1,SETVAL,arg1); **/ /* 申请共享内存区 资源 */ if((shmid=shmget(IPC_PRIVATE,4096,0660))==-1) { perror("shmget()"); exit(1); } /* 申请消息队列 资源 */ if((msgid=msgget(IPC_PRIVATE,0660))==-1) { perror("msgget()"); exit(1); } /* 主循环 */ for(;;) { PrintText(); for(;;) { cCommand=getchar(); if(cCommand=='\n' || cCommand=='\r') continue; else if(cCommand==-1 && errno==EINTR) { /* 查询是否还有被阻塞的 SIGCHLD信息,并*/ /** sigemptyset(&pendset); sigemptyset(&maskset); sigpending(&pendset); if(sigismember(&pendset,SIGCHLD)) { sigsuspend(&maskset); printf("\n发现pinding signal ---SIGCHLD"); } **/ intrcount++; continue; } else break; } switch(cCommand) { case '1' : if(ChldNum!=0) printf("\nInstance has ran !"); else for(i=0;i<PROCESS_BUF_SIZE;i++) { tmp_pid=fork(); if(tmp_pid==-1) { fprintf(stderr,"\nProcess(%d) create fail !\n %s",i,strerror(errno)); ChildSet[i]=-1; } else if (tmp_pid>0) { ChildSet[i]=tmp_pid; ChldNum++; } else { printf("\nPID = %ld is running ...",(long)getpid()); if(execve("./my.sh",NULL,NULL)==-1) perror("execve() fail!"); //sleep(12); exit(1); } } break; case '2' : for(i=0;i<PROCESS_BUF_SIZE;i++) if(ChildSet[i]!=-1) { //kill(ChildSet[i],SIGTERM); kill(ChildSet[i],9); ChildSet[i]=-1; ChldNum--; } break; case 'q' : /* 释放各种IPC资源 */ if(semctl(semid,0,IPC_RMID)==-1) perror("semctl(IPC_RMID)"); if(shmctl(shmid,IPC_RMID,NULL)==-1) perror("shmctl(IPC_RMID)"); if(msgctl(msgid,IPC_RMID,NULL)==-1) perror("msgctl(IPC_RMID)"); printf("\nwaitcount=%d,intrcount=%d \n",waitcount,intrcount); break; default: printf("\nchoice error, Try it again !"); } if (cCommand=='q') break; }} int main(){ MultiProcess(); exit(0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -