嵌入式Linux应用开发---进程通信 管道

目录

进程间通信概述

管道通信

信号通信

共享内存


 

进程间通信概述

为什么需要进程间通信?

  1. 数据传输:一个进程需要将它的数据发送给另一个进程
  2. 资源共享:多个进程之间共享相同的资源。
  3. 事件通知:一个进程需要向另一个或一组进程发送消息,通知它们发送了某种事件。
  4. 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程)此时控制进程希望能够拦截另一个进程所有操作,并能及时知道它的状态改变

Linux进程间通信(IPC)由下面及部分发展而来:

  1. UNIX进程间通信
  2. 基于System V进程间通信
  3. POSIX进程间通信

什么是管道?

管道是单向的、先进先出的,它把一个进程的输出和另一个进程的输入连接在一起。

一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)从管道的头部读出数据。

管道包括无名管道和有名管道两种:

无名管道用于父进程和子进程间的通信

有名管道用于运行于同一系统中的任意两个进程间的通信。

无名管道由pipe()函数创建:   int pipe(int fieldis[2]);

当一个管道建立时,它会创建两个文件描述符

                        fieldis[0]用于读管道,fieldis[1]用于写管道

管道关闭:关闭管道只需要将这两个文件描述符关闭即可,可以使用普通的close函数逐个关闭。

  父进程向管道中写数据,子进程从管道中读数据。

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
	int pipe_fd[2];
	pid_t pid;
	char buf_r[100];
	char *p_wbuf;
	int r_num;
	
	memset(buf_r,0,sizeof(buf_r));
	
	/*创建管道*/
	if(pipe(pipe_fd)<0)
	{
		printf("pipe create error\n");
		return -1;
	}
	/*创建子进程*/
	if((pid = fork())==0)
	{
		printf("\n");
		close(pipe_fd[1]);
		sleep(2);//为什么要睡眠?
		if((r_num = read(pipe_fd[0],buf_r,100))>0)
		{
			printf("%d numbers read from the pipe is %s\n",r_num,buf_r);
		}
		close(pipe_fd[0]);
		exit(0);
	}
	else if(pid>0)
	{
		close(pipe_fd[0]);
		if(write(pipe_fd[1],"hello",5)!= -1)
			printf("parent write hello\n");
		if(write(pipe_fd[1],"world",5)!= -1)
			printf("parent write world\n");
		close(pipe_fd[1]);
		sleep(3);
		wait(pid,NULL,0);//等待子进程结束
		exit(0);
	}
	return 0;
	
}

代码运行结果:


有名管道:与无名管道基本相同,不同点在于:无名管道只能由父子进程使用,但是通过有名管道,不相关的进程也能交换数据。

 

 

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

#define FIFO_SERVER "/tmp/myfifo"
int main(int argc,char **argv)
{
	int fd;
	char w_buf[100];
	int nwrite;
	/*打开管道*/
	fd = open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
        if(argc == 1)
	{
		printf("Please,send something:\n");
		exit(-1);
	}
	
	strcpy(w_buf,argv[1]);
	/*向管道写入数据*/
	if((nwrite = write(fd,w_buf,100))==-1)
	{
		if(errno == EAGAIN)
		{
			printf("The FIFO has not been read yet. Please try later.\n");
		}
	}
	else
	{
		printf("write %s to the FIFO \n",w_buf);
	}
	return 0;
	
}

 

 

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

#define FIFO "/tmp/myfifo"
int main(int argc,char **argv)
{
	int fd;
	char r_buf[100];
	int n_read;
	/*创建管道*/
	if((mkfifo(FIFO,O_CREAT|O_EXCL) < 0) && (errno != EEXIST))
		printf("cannot create fifoserver\n");
	printf("Prepring for reading bytes...\n");
	memset(r_buf,0,sizeof(r_buf));
        /*打开管道*/
	fd = open(FIFO,O_RDONLY|O_NONBLOCK,0);
	if(fd == -1)
	{
		perror("open");
		exit(1);
	}
	while(1)
	{
		memset(r_buf,0,sizeof(r_buf));
		if((n_read = read(fd,r_buf,100)) == -1)
		{
			if(errno == EAGAIN)
			    printf("no data yet\n");	
		}
		printf("read %s from FIFO\n",r_buf);
		sleep(1);
	}
	pause();
	return 0;
	
}

 

 

https://www.cnblogs.com/52php/p/5840229.html

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aFakeProgramer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值