目录
2.如何创建有名管道? -> mkfifo() -> man 3 mkfifo (先进先出)
3.例子1:尝试在家目录下创建一个有名管道,名字为fifo1
一、进程之间通信方式(重点)
1.为什么要实现进程之间的通信
例如:
./project -> 开启了一个名字叫project的进程。
./test -> 开启了一个名字叫test的进程。
通过学习进程之间的通信,使得不同的进程之间能够实现数据的交换,例如test进程发送数据给project进程,project进程收到数据之后,
根据数据做出相应的事情。 (test进程控制project进程)
2.在linux下,进程之间通信方式有哪些,都有什么特点
以下几种进程之间的通信有一个共通的特点,都是只能在同一台主机内部的进程使用。
1)管道通信。-->pipe
管道通信分为有名管道与无名管道,管道是一个特殊的文件,进程通过将数据写入到管道中,另外一个进程从管道中读取数据出来。
2)信号
在linux下,有非常多的信号,例如:暂停,继续,停止...,某一个进程通过发送信号给另外一个进程,从而控制另外一个进程的运行状态。
3)消息队列 -->message
某一个进程把消息发送到队列上,另外一个进程就可以读取队列上的数据,消息队列好处:进程可以读取队列上某一个特定的数据。
4)共享内存 -->share mem
多个进程访问同一片内存空间。
5)信号量
二、进程之间通信方式之一 无名管道
1.什么是无名管道?作用机制如何?
无名管道只能作用于亲缘关系的进程之间的通信,例如父子进程。无名管道就是一个没有名字的管道文件,相当于一个队列结构,fd[1]为写入端(入队),fd[0]为读出端(出队)。其中信息读出后即删除,再次读取时即为下一个信息。
2.创建一个无名管道文件
#include <unistd.h>
int pipe(int pipefd[2]); -> 执行这个函数之后,得到两个文件描述符 // int *pipefd
函数作用:
创建一个无名管道文件
参数:
pipefd 一个具有2个int类型变量的数组。(2个文件描述符)
返回值:
成功:0
失败:-1
注意:
>1、pipefd[0] -> 读端 pipefd[1] -> 写端
>2、没有名字,因此无法使用 open( )。
>3、只能用于亲缘进程间(比如父子进程、兄弟进程、祖孙进程……)通信,因为他只能在一个进程中被创建出来,然后通过继承的方式将他的文件描述符传递给子进程
>4、半双工(单方向)工作方式:读写端分开。
3.例子1: 初始化的读端写端的文件描述符是多少?
#include<stdio.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
int fd[2];
//创建一个无名管道文件 ,创建成功之后 pipefd[0] 读端 pipefd[1] 写端
pipe(fd);
printf("fd[0]:%d fd[1]:%d\n",fd[0],fd[1]); //3 4
return 0;
}
说明:无名管道文件描述符的值,是从1024个值里面按照顺序拿取
4.例子2:实现使用无名管道,让父子进程通信
#include<stdio.h>
#include <unistd.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
int fd[2];
//创建一个无名管道文件 ,创建成功之后 fd[0] 读端 fd[1] 写端
pipe(fd); //注意,不可以使用open打开无名管道,因为它没有名字,创建的时候默认已经打开了
//创建一个子进程 ,实现父进程与子进程的通信
pid_t id = fork();
if(id == -1)/