进程间通信—>无名管道、有名管道、信号通信、共享内存、消息队列、信号灯,socket
通信领域的几个概念:
单工通信:数据的传送方向为单向
半双工通信:数据的传送方向为双向,但不同时。
全双工通信:数据的传送方向为双向,且同时。
1.无名管道
是用pipe创建的一个内核文件,用于具有亲缘关系的进程之间。
int pipe(int fd[2]);
参数:pipe fd[2]:数组。
fd[0]用来标识读管道文件。
fd[1]用来标识写管道文件。
返回值:0:成功;-1:失败;
无名管道的特点:
1.只能用于具有亲缘关系的进程间通信。
2.是一种单工通信模式(理论上:可以实现双工,但是双方的收发顺序不好控制,多用做单工通信。)
3.无名管道的数据存放在内存中,管道中的数据读走后就不存在了,无名管道只存在于内核中,在文件系统中不可见。
无名管道子进程写,父进程读案例:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#define BUF_SIZE 20
int main()
{
//1.pipe
int fd[2]={0};
if(0!=pipe(fd))
{
printf("pipe create error\r\n");
return -1;
}
printf("1.create pipe success\r\n");
//2 fork
pid_t pid=-1;
pid=fork();
if(-1==pid)
{
return -1;
}
char buf[BUF_SIZE]={0};
if(0==pid)
{
//子进程 write
//关闭子进程的读管道
close(fd[0]);
printf("child process\r\n");
strcpy(buf,"child to parent\r\n");
write(fd[1],buf,BUF_SIZE);
//fd[1]写入
}
else
{
//父进程 read
//关闭父进程的fd[1]写通道
close(fd[1]);
printf("parent process\r\n");
read(fd[0],buf,BUF_SIZE);
printf("parent read:%s\r\n",buf);
}
return 0;
}
2.有名管道
有名管道:是用mkfifo创建的一个内核文件,用于任意两个进程之间的通信。管道文件在文件系统中可见。
双工是通过两个管道文件实现的。
int mkfifo(const char *pathname,mode_t mode);
作用:创建一个有名管道文件。
参数1:*pathname:有名管道文件的名称
参数2:mode 文件权限
返回值:0成功;-1失败;
ret =mkfifo("fifo",0666);//创建文件失败,并且改文件不存在
if(ret<0&&EEXIST!=erron)
{
return -1;//创建文件失败
}
//创建文件失败,但是该文件存在--->创建文件成功
A进程:
1 mkfifo–>有名称
2 open
3 write
B进程:
1 mkfifo -->找到
2 open
3 read
有名管道的特点
1.有名管道可以用于任意两个进程间的通信
2.可以实现双工通信
3.有名管道的数据存放在内存中,管道中的数据读走后就不存在了,有名管道在文件系统中可见,文件大小为0。
3.信号通信
信号:信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式(被通信方不知道什么时候被通信)。
信号:linux操作系统预先定义好了64个信号。
kill -l:可以查看当前系统提供的所有信号。
kill -9 进程号:给内核发送SIGKILL信号,让内核杀死指定进程。
singal(信号,自定义信号对应的处理函数)—>用来改变一个信号对应的默认处理动作
信号:信号是对中断的模拟,信号通信是一种异步通信方式,是一个通知。
中断:是指CPU在执行程序的过程中插入了另外一段程序的执行过程。
段程序的过程
分析alarm singal
用户进程对信号的响应方式:
1.捕获信号
2.忽略信号
3.采用默认处理动作
信号处理流程
实现两个进程的异步通信:
收信号进程:用singal pause
发信号进程:kill();
函数用法:kill();
int kill(pid_t pid,int sig);
参数1:pid 进程号(对方进程的)
参数2:sig 发的信号
案例:
面试考点
函数库:存放一堆接口函数的文件。(函数库里没有主函数,静态库,动态库)
动态库、静态库的区别:
1.后缀不同,.a .so
2.使用时刻不同,编译(静态库) 运行(动态库)
3.可移植性,静态库大于动态库