- 论坛徽章:
- 1
|
经常有人问IPC的问题,下面是一些简单的例子。有空看看!
System V信号量
- #define PERMS S_IRUSR|S_IWUSR
- void init_semaphore_struct(struct sembuf *sem,int semnum,
- int semop,int semflg)
- {
- /* 初始话信号灯结构 */
- sem->;sem_num=semnum;
- sem->;sem_op=semop;
- sem->;sem_flg=semflg;
- }
- int del_semaphore(int semid)
- {
- /* 信号灯并不随程序的结束而被删除,如果我们没删除的话(将1改为0)
- 可以用ipcs命令查看到信号灯,用ipcrm可以删除信号灯的
- */
- #if 1
- return semctl(semid,0,IPC_RMID);
- #endif
- }
- int main(int argc,char **argv)
- {
- char buffer[MAX_CANON],*c;
- int i,n;
- int semid,semop_ret,status;
- pid_t childpid;
- struct sembuf semwait,semsignal;
- if((argc!=2)||((n=atoi(argv[1]))<1))
- {
- fprintf(stderr,"Usage:%s number\n\a",argv[0]);
- exit(1);
- }
- /* 使用IPC_PRIVATE 表示由系统选择一个关键字来创建 */
- /* 创建以后信号灯的初始值为0 */
- if((semid=semget(IPC_PRIVATE,1,PERMS))==-1)
- {
- fprintf(stderr,"[%d]:Acess Semaphore Error:%s\n\a",
- getpid(),strerror(errno));
- exit(1);
- }
- /* semwait是要求资源的操作(-1) */
- init_semaphore_struct(&semwait,0,-1,0);
- /* semsignal是释放资源的操作(+1) */
- init_semaphore_struct(&semsignal,0,1,0);
- /* 开始的时候有一个系统资源(一个标准错误输出) */
- if(semop(semid,&semsignal,1)==-1)
- {
- fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a",
- getpid(),strerror(errno));
- if(del_semaphore(semid)==-1)
- fprintf(stderr,"[%d]:Destroy Semaphore Error:%s\n\a",
- getpid(),strerror(errno));
- exit(1);
- }
- /* 创建一个进程链 */
- for(i=0;i if(childpid=fork()) break;
- sprintf(buffer,"[i=%d]-->;[Process=%d]-->;[Parent=%d]-->;[Child=%d]\n",
- i,getpid(),getppid(),childpid);
- c=buffer;
- /* 这里要求资源,进入原子操作 */
- while(((semop_ret=semop(semid,&semwait,1))==-1)&&(errno==EINTR));
- if(semop_ret==-1)
- {
- fprintf(stderr,"[%d]:Decrement Semaphore Error:%s\n\a",
- getpid(),strerror(errno));
- }
- else
- {
- while(*c!='\0')fputc(*c++,stderr);
- /* 原子操作完成,赶快释放资源 */
- while(((semop_ret=semop(semid,&semsignal,1))==-1)&&(errno==EINTR));
- if(semop_ret==-1)
- fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a",
- getpid(),strerror(errno));
- }
- /* 不能够在其他进程反问信号灯的时候,我们删除了信号灯 */
- while((wait(&status)==-1)&&(errno==EINTR));
- /* 信号灯只能够被删除一次的 */
- if(i==1)
- if(del_semaphore(semid)==-1)
- fprintf(stderr,"[%d]:Destroy Semaphore Error:%s\n\a",
- getpid(),strerror(errno));
- exit(0);
- }
复制代码
SystemV消息队列
- #define MSG_FILE "server.c"
- #define BUFFER 255
- #define PERM S_IRUSR|S_IWUSR
- struct msgtype {
- long mtype;
- char buffer[BUFFER+1];
- };
- int main()
- {
- struct msgtype msg;
- key_t key;
- int msgid;
- if((key=ftok(MSG_FILE,'a'))==-1)
- {
- fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno));
- exit(1);
- }
- if((msgid=msgget(key,PERM|IPC_CREAT|IPC_EXCL))==-1)
- {
- fprintf(stderr,"Creat Message Error:%s\a\n",strerror(errno));
- exit(1);
- }
- while(1)
- {
- msgrcv(msgid,&msg,sizeof(struct msgtype),1,0);
- fprintf(stderr,"Server Receive:%s\n",msg.buffer);
- msg.mtype=2;
- msgsnd(msgid,&msg,sizeof(struct msgtype),0);
- }
- exit(0);
- }
- --------------------------------------------------------------------------------
- 客户端(client.c)
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define MSG_FILE "server.c"
- #define BUFFER 255
- #define PERM S_IRUSR|S_IWUSR
- struct msgtype {
- long mtype;
- char buffer[BUFFER+1];
- };
- int main(int argc,char **argv)
- {
- struct msgtype msg;
- key_t key;
- int msgid;
- if(argc!=2)
- {
- fprintf(stderr,"Usage:%s string\n\a",argv[0]);
- exit(1);
- }
- if((key=ftok(MSG_FILE,'a'))==-1)
- {
- fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno));
- exit(1);
- }
- if((msgid=msgget(key,PERM))==-1)
- {
- fprintf(stderr,"Creat Message Error:%s\a\n",strerror(errno));
- exit(1);
- }
- msg.mtype=1;
- strncpy(msg.buffer,argv[1],BUFFER);
- msgsnd(msgid,&msg,sizeof(struct msgtype),0);
- memset(&msg,'\0',sizeof(struct msgtype));
- msgrcv(msgid,&msg,sizeof(struct msgtype),2,0);
- fprintf(stderr,"Client receive:%s\n",msg.buffer);
- exit(0);
- }
复制代码
SystemV共享内存
- #define PERM S_IRUSR|S_IWUSR
- int main(int argc,char **argv)
- {
- int shmid;
- char *p_addr,*c_addr;
- if(argc!=2)
- {
- fprintf(stderr,"Usage:%s\n\a",argv[0]);
- exit(1);
- }
- if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1)
- {
- fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno));
- exit(1);
- }
- if(fork())
- {
- p_addr=shmat(shmid,0,0);
- memset(p_addr,'\0',1024);
- strncpy(p_addr,argv[1],1024);
- exit(0);
- }
- else
- {
- c_addr=shmat(shmid,0,0);
- printf("Client get %s",c_addr);
- exit(0);
- }
- }
复制代码 |
|