一、通讯的意义
1、传输数据:进程之间的通讯
2、共享资源:不同进程之间共享同一资源
3、事件通知:一个进程向另一个或另一组进程发送消息通知
4、进程控制:如Debug进程等需要完全控制另一个进程的执行,即能拦截进程操作并知晓其状态
二、通讯的方式
1、无名管道:pipe (使用文件操作函数: read, write, close),用于父子进程间的通信
2、有名管道:FIFO (使用文件操作函数: open, read, write, close),用于任意两个进程之间的通信
3、信号:signal
4、消息队列
5、内存共享
6、信号量:semaphore
7、套接字:socket
三、管道通讯的特点
1、管道通讯方向:有固定的读端和写端
2、数据不保留:当数据被进程从管道读出后,管道中的数据就不存在了
3、进程阻塞:进程在读或写数据时进程会阻塞(相当于等待完成管道操作)
4、管道容量固定:64KB (/include/Linux/pipe_fs_i.h)
5、管道数据:数据保存于文件中。也就是说操作管道相当于操作文件(可用函数open,read,write,close)
四、函数学习
1、无名管道:pipe
1)函数原型
int pipe(int pipefd[2]);
2)所属头文件
#include <unistd.h>
3)返回值
成功: 0
失败: -1
4)参数说明
pipefd:存储两个文件描述符
pipefd[0]: 指向管道读端
pipefd[1]: 指向管道写端
* 无名管道案例(无名管道用于父子进程之间的通讯)
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
void main()
{
pid_t pid = 0;
char *str = "I love linux, hahaha~~"; //要写入的数据
int pipefd[2]; //无名管道文件
char read_buf[23]; //读取信息缓存
/* 创建管道, 需要在fork之前创建 */
pipe(pipefd);
/* 创建子进程 */
pid = fork();
if (pid > 0)
{
/* 父进程 */
write(pipefd[1], str, 22);
printf("Father Write: ");
puts(str);
/* 等待子进程读取信息 */
wait(NULL);
close(pipefd[1]);
exit(0);
}
else
{
/* 子进程 */
read(pipefd[0], read_buf, 22);
read_buf[22] = '\0'; //结束标志
puts(read_buf);
close(pipefd[0]);
exit(0);
}
}
2、有名管道
1)创建有名管道:mkfifo
a)函数原型
int mkfifo(const char *pathname, mode_t mode);
b)所属头文件
#include <sys/types.h>
#include <sys/stat.h>
c)返回值
成功: 0
失败: -1
d)参数说明
pathname: 要创建的fifo文件的名字(含路径)
mode: 创建的fifo文件的访问权限
2)删除有名管道:unlink
a)函数原型
int unlink(const char *pathname);
b)所属头文件
#include <unistd.h>
c)返回值
成功: 0
失败: -1
d)参数说明
pathname: 要删除的文件名
* 案例 - 1: 写管道
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
void main()
{
int fd = 0;
/* Create fifo file. */
mkfifo("./fifo_file", 0666);
/* Open fifo file. */
fd = open("./fifo_file", O_WRONLY);
/* Write data to the fifo file. */
write(fd, "I love linux!", 13);
/* Close fifo file */
close(fd);
puts("Fifo file was read !");
}
* 案例 - 2: 读管道
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
void main()
{
char c_buf[15];
int fd = 0;
/* Open fifo file. */
fd = open("./fifo_file", O_RDONLY);
/* Read fifo data. */
read(fd, c_buf, 13);
c_buf[13] = '\0';
printf("Fifo data: %s\n", c_buf);
/* Close fifo file. */
close(fd);
/* Delete fifo file. */
unlink("./fifo_file");
}
* 案例 - 1 和 案例 - 2 运行结果:
* unlink的功能为删除管道, 也就是删除有名管道文件:fifo_file(文件名任意取)