写出三种进程间通信的代码示例
有名管道
创建两个有名管道文件
#include <myhead.h>
int main(int argc, const char *argv[])
{if(mkfifo("pipe1",0664)==-1){perror("mkfifo pipe1 error");return -1;}if(mkfifo("pipe2",0664)==-1){perror("mkfifo pipe2 error");return -1;}printf("关闭请按回车\n");getchar();system("rm pipe1");system("rm pipe2");return 0;
}
发送
#include <myhead.h>
int main(int argc, const char *argv[])
{int wfd=-1;if((wfd=open("./mypipe",O_WRONLY))==-1){perror("wfd open error");return -1;}char wbuf[128]="";while(1){printf("请输入>>>>");fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]=0;write(wfd,wbuf,sizeof(wbuf));if(strcmp(wbuf,"quit")==0){break;}}close(wfd);return 0;
}
接收
#include <myhead.h>
int main(int argc, const char *argv[])
{int rfd=-1;if((rfd=open("./mypipe",O_RDONLY))==-1){perror("rfd open error");return -1;}char rbuf[128]="";while(1){read(rfd,rbuf,sizeof(rbuf));printf("收到一条消息:%s\n",rbuf);if(strcmp(rbuf,"quit")==0){break;}}close(rfd);return 0;
}
消息队列
发送
#include <myhead.h>
struct msgbuf
{long mtype;char mtext[1024];
};
#define SIZE (sizeof(struct msgbuf)-sizeof(long))
int main(int argc, const char *argv[])
{key_t key=ftok("/",'k');if(key==-1){perror("key create error");return -1;}printf("key=%#x\n",key);int msgid=msgget(key,IPC_CREAT|0664);if(msgid==-1){perror("msgget error");return -1;}printf("msgid=%d\n",msgid);struct msgbuf buf;while(1){printf("请输入您要发送的类型\n");scanf("%ld",&buf.mtype);printf("请输入消息内容\n");scanf("%s",buf.mtext);msgsnd(msgid,&buf,SIZE,0);if(strcmp(buf.mtext,"quit")==0){break;}}return 0;
}
接收
#include <myhead.h>
struct msgbuf
{long mtype;char mtext[1024];
};
#define SIZE (sizeof(struct msgbuf)-sizeof(long))
int main(int argc, const char *argv[])
{key_t key=ftok("/",'k');if(key==-1){perror("key create error");return -1;}printf("key=%#x\n",key);int msgid=msgget(key,IPC_CREAT|0664);if(msgid==-1){perror("msgget error");return -1;}printf("msgid=%d\n",msgid);struct msgbuf buf;while(1){msgrcv(msgid,&buf,SIZE,10,0);printf("收到消息%s\n",buf.mtext);if(strcmp(buf.mtext,"quit")==0){break;}}return 0;
}
信号灯集
头文件
#ifndef __SEM_H__
#define __SEM_H__
#include <myhead.h>
//信号灯集的申请,初始化信号灯,并返回信号灯集的id
int create_sem(int semcount);
//申请信号灯资源操作 p操作
int P(int semid,int semno);
//释放信号灯资源操作 v操作
int V(int semid,int semno);
//信号灯集的删除
int del_sem(int semid);#endif
#include "sem.h"union semun {int val; /* Value for SETVAL */struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET*/unsigned short *array; /* Array for GETALL, SETALL */struct seminfo *__buf; /* Buffer for IPC_INFO(Linux-specific) */};
int init_sem(int semid,int semno)
{int val=-1;printf("请输入标号为%d的灯的初始值:",semno);scanf("%d",&val);getchar();union semun us;us.val=val;if(semctl(semid,semno,SETVAL,us)==-1){perror("set val error");return -1;}return 0;
}
//信号灯集的申请,初始化信号灯,并返回信号灯集的id
int create_sem(int semcount)
{//1.创建key值key_t key=ftok("/",'y');if(key==-1){perror("fork error");return -1;}//2.通过key值创建一个信号灯集int semid=semget(key,semcount,IPC_CREAT |IPC_EXCL|0664);if(semid==-1){if(errno==EEXIST){semid=semget(key,semcount,IPC_CREAT);return semid;}else{perror("semget error");return -1;}}//3.给信号灯集中的信号灯进行初始化操作for(int i=0;i<semcount;i++){init_sem(semid,i);}return semid;
}
//申请信号灯资源操作 p操作
int P(int semid,int semno)
{struct sembuf buf;buf.sem_num=semno;buf.sem_op=-1;buf.sem_flg=0;if(semop(semid,&buf,1)==-1){perror("P error");return -1;}return 0;
}
//释放信号灯资源操作 v操作
int V(int semid,int semno)
{struct sembuf buf;buf.sem_num=semno;buf.sem_op=1;buf.sem_flg=0;if(semop(semid,&buf,1)==-1){perror("V error");return -1;}return 0;}
//信号灯集的删除
int del_sem(int semid)
{if(semctl(semid,0,IPC_RMID,0)==-1){perror("del error");return -1;}return 0;
}
发送
#include "sem.h"
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{int semid=create_sem(2);if(semid==-1){perror("creat_sem error");return -1;}//1.创建一个key值key_t key=ftok("/",'t');if(key==-1){perror("ftok error");return -1;}printf("key=%#x\n",key);//2.通过key值创建共享内存段int shmid=shmget(key,PAGE_SIZE,IPC_CREAT|0664);if(shmid==-1){perror("shmget error");return -1;}printf("shmid=%d",shmid);//3.将共享内存映射到用户空间char *addr=shmat(shmid,NULL,0);if(addr==(void *)-1){printf("shmat error");return -1;}//4.使用共享内存段while(1){P(semid,1);printf("please enter");fgets(addr,PAGE_SIZE,stdin);addr[strlen(addr)-1]=0;V(semid,0);if(strcmp(addr,"quit")==0){break;}}//5.取消映射if(shmdt(addr)==-1){perror("shmdt error");return -1;}//6.删除共享内存if(shmctl(shmid,IPC_RMID,0)==-1){perror("shmctl error");return -1;}return 0;
}
接收
#include "sem.h"
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{int semid=create_sem(2);if(semid==-1){perror("creat_sem error");return -1;}//1.创建一个key值key_t key=ftok("/",'t');if(key==-1){perror("ftok error");return -1;}printf("key=%#x\n",key);//2.通过key值创建共享内存段int shmid=shmget(key,PAGE_SIZE,IPC_CREAT|0664);if(shmid==-1){perror("shmget error");return -1;}printf("shmid=%d",shmid);//3.将共享内存映射到用户空间char *addr=shmat(shmid,NULL,0);if(addr==(void *)-1){printf("shmat error");return -1;}//4.使用共享内存段while(1){P(semid,0);printf("共享内存中的数据为:%s\n",addr);V(semid,1);if(strcmp(addr,"quit")==0){break;}}//5.取消映射if(shmdt(addr)==-1){perror("shmdt error");return -1;}//6.删除共享内存if(shmctl(shmid,IPC_RMID,NULL)==-1){perror("shmctl error");return -1;}del_sem(semid);return 0;
}