2、进程通信

进程通信

1、进程建通信概述

1、目的:

为何需要进程间通信?

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

2、来源:

linux进程间通信(IPC)是由以下几部分发展而来:
1、UNIX进程间通信;
2、基于system V进程间通信;
3、POSIX进程间通信;

注意:
posix是可移植操作系统接口;

3、进程间通讯方式包括:

1、管道(pipe)和有名管道(FIFO)
2、信号(signal)
3、消息队列
4、共享内存
5、信号量
6、套接字(socket)

2、管道通讯

特点:先进先出,尾进头出;
1、管道创建:
管道包括无名管道和有名管道两种:
无名管道:用于父进程和子进程之间的通信;
有名管道:用于同一系统之间任意两个进程;

1、无名管道:

(1)通过 pipe() 函数创建无名管道:

int pipe(int filedis[2]);

当一个管道创建之后,会建立两个文件描述符:

filedis[0]:用于读管道;
filedis[1]:用于写管道;

实例 1:

创建一个管道;



#include<unistd.h>
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>

int main()
{
	int pipe_fd[2];//定义两个int类型的文件描述符;
	printf("fd[0]=%d,fd[1]=%d\n",pipe_fd[0],pipe_fd[1]);
//未创建管道符之前,
	if(pipe(pipe_fd)<0)
	{
		printf("pipe create error\n");
		return -1;	

	}
	else
	{
		//创建管道符之后,管道描述符的数值;
		printf("fd[0]=%d,fd[1]=%d\n",pipe_fd[0],pipe_fd[1]);
		printf("pipe create success\n");
	}
	
	close(pipe_fd[0]);
	close(pipe_fd[1]);
}

注意:
必须在系统调用fork()之前先调用pipe(),否则子进程将无法继承文件的描述符。
即:先铺管道,才有进程。

否则的话会创建两个管道:父进程一个,子进程一个,个用个的。

实例 2:

#include<stdio.h>
#include<sys/types.h>
#include<errno.h>
#include<unistd.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("pip 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],"pipe",5)!=-1)
			printf("parent write pipe! \n");
		close(pipe_fd[1]);
		waitpid(pid,NULL,0); /*等待子进程结束*/
		exit(0);
		

	}
	return 0;

}

结果显示:

parent write hello! 
parent write pipe! 
(sleep 210 numbers read from the pipe is hellopipe

代码分析:

read()函数的原型是

int read(int fd,void *buf,int count);

解释:

char buff[1024];
int fd1,i;
read(fd1,buff,sizeof(buff))
参数依次为:文件描述符,变量,读取长度

功能是“从文件说明符fd相关联的文件中读取count个字符,并把这些字符存储到buf所指的缓冲区回中。

返回值是操作成功时所读到的字节数,在文件结束时可能少于count个字答节;若返回值为-1则说明出错了,返回0则表示到达文件尾端。

2、命名管道

定义:

#include<sys/types.h>
#include<sys/stat.h>

int mkfifo(const char * pathname,mode_t mode);

参数:

pathname: FIFO文件名;
mode: 属性(见文件操作章节)
一旦创建一个FIFO就可以通过open打开他,一般的文件访问函数(close,read,write等)都可以用于FIFO。

3、信号通讯

4、共享内存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值