1、要求用消息队列实现A、B进程间通信,使A、B进程能够随时收发数据
A进程:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/wait.h>
typedef void (*sighandler_t)(int);
#define ERR_MSG(msg) do{\
printf("%s %d\n",__func__,__LINE__);\
perror(msg);\
return -1;\
}while(0)
typedef struct {
long mtype;
char mtext[128];
}Msgbuf;
void handler1(int sig)
{
while(waitpid(-1,NULL,WNOHANG)>0);
exit(0);
}
void handler2(int sig)
{
exit(0);
}
int main(int argc, const char *argv[])
{
pid_t pid=fork();
if(pid>0){
if(signal(SIGCHLD,handler1)==SIG_ERR)
ERR_MSG("signal");
key_t key=ftok("./",1);
if(key<0)
ERR_MSG("ftok");
int msqid=msgget(key,IPC_CREAT|0664);
if(msqid<0)
ERR_MSG("msgget");
Msgbuf snd;
snd.mtype=1;
while(1){
bzero(snd.mtext,sizeof(snd.mtext));
printf("请输入>>>");
fgets(snd.mtext,sizeof(snd.mtext),stdin);
snd.mtext[strlen(snd.mtext)-1]=0;
if(msgsnd(msqid,&snd,sizeof(snd.mtext),0)<0)
ERR_MSG("msgsnd");
if(strcasecmp(snd.mtext,"quit")==0){
if(kill(pid,SIGUSR1)!=0)
ERR_MSG("kill");
break;
}
}
}else if(0==pid){
if(signal(SIGUSR1,handler2)==SIG_ERR)
ERR_MSG("signal");
key_t key=ftok("./",1);
if(key<0)
ERR_MSG("ftok");
int msqid=msgget(key,IPC_CREAT|0664);
if(msqid<0)
ERR_MSG("msgget");
Msgbuf rcv;
rcv.mtype=2;
while(1){
bzero(rcv.mtext,sizeof(rcv.mtext));
if(msgrcv(msqid,&rcv,sizeof(rcv.mtext),2,0)<0){
ERR_MSG("msgrcv");
}
if(strcasecmp(rcv.mtext,"quit")==0){
msgctl(msqid,IPC_RMID,NULL);
putchar(10);
break;
}
printf("\nB:%s",rcv.mtext);
fflush(stdout);
printf("\n请输入>>>");
fflush(stdout);
}
}else{
ERR_MSG("fork");
}
return 0;
}
B进程:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#define ERR_MSG(msg) do{\
printf("%s %d\n",__func__,__LINE__);\
perror(msg);\
return -1;\
}while(0)
typedef struct {
long mtype;
char mtext[128];
}Msgbuf;
void handler1(int sig)
{
while(waitpid(-1,NULL,WNOHANG)>0);
exit(0);
}
void handler2(int sig)
{
exit(0);
}
int main(int argc, const char *argv[])
{
pid_t pid=fork();
if(pid>0){
if(signal(SIGCHLD,handler1)==SIG_ERR)
ERR_MSG("signal");
key_t key=ftok("./",1);
if(key<0)
ERR_MSG("ftok");
int msqid=msgget(key,IPC_CREAT|0664);
if(msqid<0)
ERR_MSG("msgget");
Msgbuf rcv;
while(1){
bzero(rcv.mtext,sizeof(rcv.mtext));
if(msgrcv(msqid,&rcv,sizeof(rcv.mtext),1,0)<0){
ERR_MSG("msgrcv");
}
if(strcasecmp(rcv.mtext,"quit")==0){
msgctl(msqid,IPC_RMID,NULL);
if(kill(pid,SIGUSR1)!=0)
ERR_MSG("kill");
putchar(10);
break;
}
printf("\nA:%s",rcv.mtext);
fflush(stdout);
printf("\n请输入>>>");
fflush(stdout);
}
}else if(0==pid){
if(signal(SIGUSR1,handler2)==SIG_ERR)
ERR_MSG("signal");
key_t key=ftok("./",1);
if(key<0)
ERR_MSG("ftok");
int msqid=msgget(key,IPC_CREAT|0664);
if(msqid<0)
ERR_MSG("msgget");
Msgbuf snd;
snd.mtype=2;
while(1){
bzero(snd.mtext,sizeof(snd.mtext));
printf("请输入>>>");
fgets(snd.mtext,sizeof(snd.mtext),stdin);
snd.mtext[strlen(snd.mtext)-1]=0;
if(msgsnd(msqid,&snd,sizeof(snd.mtext),0)<0)
ERR_MSG("msgsnd");
if(strcasecmp(snd.mtext,"quit")==0){
break;
}
}
}else{
ERR_MSG("fork");
}
return 0;
}
测试:
2、使用共享内存实现
a. A进程写入一个整型,在该整型后,写入一个字符串
b. B进程将共享内存中的整型以及字符串读取出来
A进程:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#define ERR_MSG(msg) do{\
printf("%s %d\n",__func__,__LINE__);\
perror(msg);\
return -1;\
}while(0)
int main(int argc, const char *argv[])
{
key_t key=ftok("./",1);
if(key<0)
ERR_MSG("ftok");
int shmid=shmget(key,64,IPC_CREAT|0664);
if(shmid<0)
ERR_MSG("shmid");
int *p=(int *)shmat(shmid,NULL,0);
if(p==(int *)-1)
ERR_MSG("shmat");
*p=100;
char *str=(char *)(p+1);
strcpy(str,"hello world");
return 0;
}
B进程:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#define ERR_MSG(msg) do{\
printf("%s %d\n",__func__,__LINE__);\
perror(msg);\
return -1;\
}while(0)
int main(int argc, const char *argv[])
{
key_t key=ftok("./",1);
if(key<0)
ERR_MSG("ftok");
int shmid=shmget(key,64,IPC_CREAT|0664);
if(shmid<0)
ERR_MSG("shmid");
int *p=(int *)shmat(shmid,NULL,0);
if(p==(int *)-1)
ERR_MSG("shmat");
printf("%d\n",*p);
char *str=(char *)(p+1);
printf("%s\n",str);
return 0;
}
测试: