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

📄 ipc.c

📁 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 + -