linux内核编程之进程通信(管道+MQ)

博客围绕管道和MQ的进程通信展开。利用两个管道实现父子进程双向通信,将整数x从1加到10;还展示了用MQ实现一个进程发消息、另一个进程收消息的代码,体现了不同方式在进程通信中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

管道

有这样一道题目:利用两个管道进行双向通信,实现父子进程协作把整数x从1加到10。

因为普通管道是单向通信的,所以,两个管道就可以双向通信了(达到类似于MQ的效果)。

代码如下:

/*
* @Author: smile丶
* @Date:   2019-06-14 09:36:52
* @Last Modified by:   smile丶
* @Last Modified time: 2019-06-14 10:02:13
*/
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(int argc, char const *argv[])
{
        int fd1[2],fd2[2],sum=0,pid;
        //创建管道
        if(pipe(fd1)<0){
                perror("pipe");
                exit(1);
        }
        if(pipe(fd2)<0){
                perror("pipe");
        }
        //创建进程
        pid=fork();
        if (pid<0)
        {
                perror("fork");
                exit(1);
        }
        if (pid>0){
                //父
                write(fd1[1],&sum,sizeof(int));
                while(sum<=10){
                        close(fd2[1]);
                        read(fd2[0],&sum,sizeof(int));
                        printf("parent:%d\n",sum++ );
                        write(fd1[1],&sum,sizeof(int));
                }
                exit(0);
        }
        if(pid==0){
                //子
                while(sum<=9){
                        read(fd1[0],&sum,sizeof(int));
                        printf("child:%d\n",sum++ );
                        write(fd2[1],&sum,sizeof(int));
                }
                exit(0);
        }
        return 0;
}

MQ

简单用mq实现一个进程发送消息,另一个进程接收消息

代码如下:

/*
* @Author: smile丶
* @Date:   2019-06-16 10:09:24
* @Last Modified by:   smile丶
* @Last Modified time: 2019-06-16 10:55:47
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <unistd.h>
struct msgbuf
{
	long type;
	char text[1024];
};
int main(int argc, char const *argv[])
{
	
	key_t key;
	int qid;
	int pid;

	if( (key = ftok("/etc/profile",1))==-1 ){
		perror("ftok error");
		exit(1);
	}

	//创建消息队列
	if( ( qid = msgget(key,IPC_CREAT | 0660) )==-1 ){
		perror("msgget error");
	}
	//创建进程
	if ( (pid = fork())==0 )
	{
		//zi
		//接受信息
		while(1){
			struct msgbuf res;
			msgrcv(qid,&res,sizeof(res.text),2,0);
			if(res.text[0]=='q'){
				if(msgctl(qid,IPC_RMID,NULL)==0){
					printf("删除信息队列成功!\n");
				}
				exit(0);
			}
			printf("child %d accept info %s\n", getpid(),res.text);
		}
	}
	else if ( pid>0 )
	{

		//fu
		struct msgbuf m;
		m.type = 2;
		while(1){
			printf("请输入你想说的!(q:退出)\n");
			scanf("%s",m.text);
			printf("parent %d send %s\n",getpid(),m.text);
			msgsnd(qid,&m,sizeof(m.text),0);
			if(m.text[0]=='q')
				exit(0);
			printf("send seccess!!!\n");
		}
		
					
	}else{
		perror("fork error");
	}
	return 0;
}

管道实现形式:

/*
* @Author: smile丶
* @Date:   2019-06-16 10:50:57
* @Last Modified by:   smile丶
* @Last Modified time: 2019-06-16 11:23:53
*/
#include <stdio.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
	

	int fd[2];
	int pid;
	if ( pipe(fd)<0 )
	{
		perror("fd error");
		/* code */
	}

	if ( (pid = fork())==0)
	{
		while(1){
			close(fd[1]);
			char res[1024];
			read(fd[0],res,sizeof(res));
			printf("child %d 读到数据: %s\n",getpid(),res );
			if (res[0]=='q')
			{
				break;
				/* code */
			}
		}
		exit(0);
		/* code */
	}else if (pid > 0)
	{
		while(1){
			close(fd[0]);
			char send[1024];
			printf("请输入要发送的数据\n");
			scanf("%s",send);
			printf("father %d sending\n",getpid());
			write(fd[1],send,sizeof(send));
			printf("sending success!!!\n");
			if (send[0]=='q')
			{
				break;	
				/* code */
			}
		}
		exit(0);
		/* code */
	}else{
		perror("pid error");
	}
	wait(NULL);
	return 0;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值