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

管道

有这样一道题目:利用两个管道进行双向通信,实现父子进程协作把整数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
#include
#include
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 
#include 
#include 
#include 
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 
#include 
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;
}

 

 

 

你可能感兴趣的:(linux)