1. 写出三种进程间通信的代码示例
1. 无名管道
#include
int main(int argc, const char *argv[])
{
//定义进程号变量
pid_t pid = -1;
//定义存放管道文件描述符的数组
int pipefd[2] = {0};
//创建管道文件
if(pipe(pipefd) == -1)
{
perror("pipe error");
return -1;
}
printf("pipefd[0] = %d, pipefd[1] = %d\n", pipefd[0], pipefd[1]);
//创建一个子进程
pid = fork();
if(pid > 0)
{
//父进程
//关闭父进程中管道的读端
close(pipefd[0]);
char buf[128] = "";
while(1)
{
//从终端上获取数据放入buf中
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = 0; //将'\n'换成'\0'
write(pipefd[1], buf, sizeof(buf)); //将数据写入管道文件中
if(strcmp(buf, "quit") == 0)
{
break;
}
}
//关闭写端
close(pipefd[1]);
}else if(pid == 0)
{
//子进程
//子进程关闭管道的写端
close(pipefd[1]);
char rbuf[128] = "";
while(1)
{
bzero(rbuf, sizeof(rbuf)); //将数组内容置0
read(pipefd[0], rbuf, sizeof(rbuf)); //从管道文件中读取数据
printf("收到父进程消息: %s\n", rbuf);
if(strcmp(rbuf, "quit") == 0)
{
break;
}
}
//关闭读端
close(pipefd[0]);
//退出子进程
exit(EXIT_SUCCESS);
}else
{
perror("fork error");
return -1;
}
//父进程回收子进程的资源
wait(NULL);
return 0;
}
2. 有名管道
//发送端
#include
int main(int argc, const char *argv[])
{
//1、打开管道文件
int wfd= -1;
if((wfd = open("./myfifo", 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
int main(int argc, const char *argv[])
{
//1、打开管道文件
int rfd= -1;
if((rfd = open("./myfifo", O_RDONLY)) == -1)
{
perror("rfd open error");
return -1;
}
//从管道文件中读取数据
char rbuf[128] = "";
while(1)
{
//清空内容
bzero(rbuf, sizeof(rbuf));
//将数据从管道文件中读取出来
read(rfd, rbuf, sizeof(rbuf));
printf("收到一条消息:%s\n", rbuf);
//判断是否要退出
if(strcmp(rbuf, "quit") == 0)
{
break;
}
}
//关闭管道文件
close(rfd);
return 0;
}
3. 消息队列
//发送端
#include
//定义一个发送消息的结构体类型
struct msgbuf
{
long mtype; //消息类型
char mtext[1024]; //消息正文大小
};
//宏定义消息正文的大小
#define SIZE (sizeof(struct msgbuf)-sizeof(long))
int main(int argc, const char *argv[])
{
//1、创建key值
key_t key = ftok("/", 'k');
if(key == -1)
{
perror("key create error");
return -1;
}
//此时key已经创建出来
printf("key = %#x\n", key);
//2、创建消息队列
int msgid = msgget(key, IPC_CREAT|0664);
if(msgid == -1)
{
perror("msgget error");
return -1;
}
printf("msgid = %d\n", msgid); //输出消息队列id号
//3、向消息队列中存放数据
//定义一个消息类型的变量
struct msgbuf buf;
while(1)
{
//输入消息内容
printf("请输入您要发送的类型:");
scanf("%ld", &buf.mtype);
printf("请输入消息内容:");
scanf("%s", buf.mtext);
//将消息放入消息队列中
msgsnd(msgid, &buf, SIZE, 0);
//判断退出条件
if(strcmp(buf.mtext, "quit") == 0)
{
break;
}
}
//4、删除消息队列
if(msgctl(msgid, IPC_RMID, NULL) == -1)
{
perror("msgctl error");
return -1;
}
return 0;
}
//接收端
#include
//定义一个发送消息的结构体类型
struct msgbuf
{
long mtype; //消息类型
char mtext[1024]; //消息正文大小
};
//宏定义消息正文的大小
#define SIZE (sizeof(struct msgbuf)-sizeof(long))
int main(int argc, const char *argv[])
{
//1、创建key值
key_t key = ftok("/", 'k');
if(key == -1)
{
perror("key create error");
return -1;
}
//此时key已经创建出来
printf("key = %#x\n", key);
//2、创建消息队列
int msgid = msgget(key, IPC_CREAT|0664);
if(msgid == -1)
{
perror("msgget error");
return -1;
}
printf("msgid = %d\n", msgid); //输出消息队列id号
//3、从消息队列中读取数据
//定义一个消息类型的变量
struct msgbuf buf;
while(1)
{
//将消息从消息队列中读取出来
msgrcv(msgid, &buf, SIZE, 0, 0);
//将读取的消息打印出来
printf("收到消息:%s\n", buf.mtext);
//判断退出条件
if(strcmp(buf.mtext, "quit") == 0)
{
break;
}
}
//4、删除消息队列
return 0;
}