通信领域的几个概念:

单工通信:数据的传送方向为单向的,发送端和接收端都是固定的,后续不可更改【广播:广播是发送端,听的人是接收端】
半双工通信:数据的传送方向为双向,但不同时,发送端和接收端不固定,但不能同时两端都为发送端或都为接收端【对讲机】
全双工通信:数据的传送方向为双向且同时(电脑)
进程间通信:两个进程数据交换
1.无名管道:实现交换的第三方的介质,存在在linux内核中,在文件系统中不可见
是用pipe创建的一个内核文件
特点:
1.只能用于具有亲缘关系(父子,子孙,兄弟)的进程间的通信,
2.是一种单工通信模式(理论上是双工的,但是通信双方的收发顺序不好控制,通常用作单工)
3.无名管道的数据存放在内存中,管道中的数据读走后就不存在了,无名管道只存在在内核中,在文件系统中不可见
不好用!!!
pipe函数:
#include//作用:创建无名管道
int pipe(int fd[2]);
//pipefd[2]:数组,fd[0]用来标识读管道文件
                 //fd[1]用来标识,写管道文件(IO函数,read,write)
//参数:有两个整数的数组
//成功返回0,失败返回-1 #include#include#include#define SIZE 30
//无名管道
int main()
{
	//创建无名管道
    //fd[0],fd[1]是文件描述符
	//fd[0]用来标识读出管道文件
	//fd[1]用来标识写入管道文件
	int fd[2]={0};
	if(0!=pipe(fd))
	{
		return -1;
	}
	printf("create piped success\r\n");
	//创建一个子进程
	pid_t pid=-1;
	pid=fork();
	if(pid==-1)
	{
		//进程未创建成功
		return -1;
	}
	char buf[SIZE]={0};
	if(pid==0)
	{
		//进入子进程,write
		
		printf("child process----\r\n");
		strcpy(buf,"child to parent");
		//write(int fd,const void *buf,size_t count)
		//参数1:文件描述符
		//参数2:要写的内存空间的首地址
		//参数3:要写的内容的大小
		write(fd[1],buf,SIZE);
		//printf("buf=%s\r\n",buf);
	}
	if(pid!=0)
	{
		//进入父进程
		printf("parent process----\r\n");
		//read(int fd,void *buf,size_t count)
		//参数1:文件描述符
		//参数2:要读的内存空间的首地址
		//参数3:要读的内容的大小
		read(fd[0],buf,SIZE);
	
		printf("read success,buf=%s\r\n",buf);
	}
	
	return 0;
}   2.有名管道(用于任意进程间的通信)
有名管道使用mkfifo创建的一个内核文件,用于任意两个进程之间的通信
管道文件在文件系统中可见
#include#includeint mkfifo(const char *pathname, mode_t mode);
//作用:创建一个有名管道
//*pathname:是有名管道文件的名称
//mode :文件的权限
//返回值:成功返回0,失败返回-1
//A进程数据传到B进程
A:
    1.mkfifo->有名称
    2.open
    3.write
B:
    1.mkfifo
    2.open
    3.read  特点:
1.有名管道可以用于任意两个进程间的通信
2.可以实现双工通信,是建立在两个管道上的
3.有名管道中的数据存放在内存中,数据读走后就没有了
4.有名管道文件在文件系统中可见,文件大小为0,因为数据存放在内存中
先写后读
#include#include#include#define SIZE 30
//无名管道
int main()
{
	//创建无名管道
	//fd[0]用来标识读出管道文件
	//fd[1]用来标识写入管道文件
	int fd[2]={0};
	if(0!=pipe(fd))
	{
		return -1;
	}
	printf("create piped success\r\n");
	//创建一个子进程
	pid_t pid=-1;
	pid=fork();
	if(pid==-1)
	{
		//进程未创建成功
		return -1;
	}
	char buf[SIZE]={0};
	if(pid==0)
	{
		//进入子进程,write
		
		printf("child process----\r\n");
		strcpy(buf,"child to parent");
		//write(int fd,const void *buf,size_t count)
		//参数1:文件描述符
		//参数2:要写的内存空间的首地址
		//参数3:要写的内容的大小
		write(fd[1],buf,SIZE);
		//printf("buf=%s\r\n",buf);
	}
	if(pid!=0)
	{
		//进入父进程
		printf("parent process----\r\n");
		//read(int fd,void *buf,size_t count)
		//参数1:文件描述符
		//参数2:要读的内存空间的首地址
		//参数3:要读的内容的大小
		read(fd[0],buf,SIZE);
	
		printf("read success,buf=%s\r\n",buf);
	}
	
	return 0;
}   先读后写
#include#include#include#include#include#include#include#define SIZE 20
int main()
{
	//1.1.mkfifoA   
	int ret=-1;
	ret=mkfifo("fifoa",0666);
	//创建文件失败并且该文件不存在
	if(ret< 0 &&EEXIST!=errno)
	{
		printf("error\r\n");
		return -1;//创建文件失败
	}
	//创建文件失败但是该文件存在--》创建文件成功
	printf("1.1:create fifoa ok!----\r\n");
	
	//1.2.mkfifoB  
	ret=mkfifo("fifob",0666);
	//创建文件失败并且该文件不存在
	if(ret< 0 &&EEXIST!=errno)
	{
		printf("error\r\n");
		return -1;//创建文件失败
	}
	//创建文件失败但是该文件存在--》创建文件成功
	printf("1.2:create fifob ok!----\r\n");
	//2.1.open fifoa
	int fdr=open("fifoa",O_RDONLY,0666);
	if(-1 == fdr)
	{
		perror("open error");
		return -1;
	}
	printf("2.1:open fifoa ok!-----\r\n");
	
	//2.2.open fifob
	int fdw=open("fifob",O_WRONLY,0666);
	if(-1 == fdw)
	{
		perror("open error");
		return -1;
	}
	printf("2.2:open fifob ok!-----\r\n");
	
	char buf[SIZE]={0};
	while(1)
	{
		
		//read
		memset(buf,0,SIZE);
		read(fdr,buf,SIZE);
		printf("a->b:%s\r\n",buf);
		
		//write
		memset(buf,0,SIZE);
		fgets(buf,SIZE,stdin);
		write(fdw,buf,SIZE);
	}
	
	//5.close
	close(fdw);
	close(fdr);
	return 0;
}       两个同时运行,可实现通信
3.信号通信 (唯一一种异步通信方式)
异步:被通信方不知道什么时候通信,
进程:task_struct+4G的虚拟空间
用户空间进程:task_struct+(0G-3G)的虚拟空间
内核空间进程:task_struct+(3G-4G)的虚拟空间
信号:linux操作系统预先定义好了64个信号(操作系统提供)
kill -l :查看当前系统提供的所有信号
kill -9 进程号:程序员调用,给内核发送SIGKILL信号,让内核杀死指定的进程号的进程


用户进程对信号的响应方式:捕获信号,忽略信号,采用默认处理动作
signal (信号,自定义的信号对应的处理函数)--->用来改变信号的默认处理状态


实现两个进程的异步通信(信号通信)
A 收信号进程:要用signal注册信号处理函数,signal ,pause
B 发信号进程:kill (),
//kill
#include#includeint kill(pid_t pid,int sig);
//参数1:对方的进程号
//参数2:要发送的信号
  同步通信和异步通信:
同步通信:发送方发数据,接收方收数据,双方需要在很短的时间内完成数据交换,否则会造成一方阻塞
异步通信:被通信方不知道通信方什么时候和它通信
#includetypedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
//作用:设置某一信号的动作
//参数1:要处理的信号类型,可以取除了SIGKILL和SIGSTOP之外的任意一种信号
//参数2:描述了与信号关联的动作-->有3个
//返回值:成功返回先前的信号处理函数指针,错误返回-1 SIG_IGN   //表示忽略该信号
-->SIG_DFL    //表示恢复对信号的系统默认处理,不写的话此处理默认也是执行系统默认处理
                   
-->sighandler_t类型的函数指针
:
        typedef void (*sighandler_t)(int);
        sighandler_t signal(int signum, sighandler_t handler);此函数必须在signal()被调用前申明,handler(参数2)中为这个函数名,当接收到一个类型为sig的信号时,就执行handler 所指定的函数,(int)signum是传递给它的唯一参数。执行了signal()调用后,进程只要接收到类型为sig的信号,不管其正在执行程序的哪一部分,就立即执行func()函数。当func()函数执行结束后,控制权返回进程被中断的那一点继续执行。

常用的Signal信号:



转载自Signal ()函数详细介绍_怀想天空2010的博客-博客_signal函数
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
文章名称:进程的通信-创新互联
文章URL:http://www.scyingshan.cn/article/shhpe.html

 建站
建站
 咨询
咨询 售后
售后
 建站咨询
建站咨询 
 