Linux下的软件编程——IPC机制
进程间通信:IPC机制
原因:进程间空间独立,无法之间通信,需要IPC机制实现通信
同一主机进程间通信:
1.古老的通信方式
无名通道 有名通道 信号:进程间通知机制
2.IPC对象通信
共享内存:效率最高 消息队列 信号量集(信号灯)
主要用在不同主机进程间通信
3.socket通信
网络通信
IPC机制:
1.管道
有名管道:可以用于同一主机,任何进程间通信
无名管道:只能用于同一主机,具有亲缘关系的进程间通信(父子进程间)
2.无名管道
(1)无名管道操作流程:
1.创建无名管道:pipe() pipefd[0]——>读端
2.写管道:write() pipefd[1]——>写端
3.读管道:read()
4.关闭管道:close()
#include <stdio.h>
#include <unistd.h>int main(int argc, const char *argv[])
{int pipefd[2];int ret = pipe(pipefd);if (ret < 0){perror("pipe error");return -1;}pid_t pid = fork();if (pid > 0){//pipefd[0] --->read //pipefd[1] --->writeclose(pipefd[0]);write(pipefd[1], "hello world", 11);close(pipefd[1]);wait(NULL);}else if (0 == pid){//pipefd[0] --->read//pipefd[1] --->writeclose(pipefd[1]);char buff[1024] = {0};read(pipefd[0], buff, sizeof(buff));printf("buff = %s\n", buff);close(pipefd[0]);}else{perror("fork error");}return 0;
}
(2)管道本质:
内核空间中的一段缓冲区,遵循先进先出特点
无名管道的:读端:pipefd[0] 写端:pipefd[1]
读写端不能交换
无名管道默认大小:65536字节=64K
(3)管道的特性
1.写阻塞:读端和写端都存在,向管道中写数据,当管道满时,发生写阻塞
2.读阻塞:读端和写端都存在,向管道中写数据,当管道为空,发生读阻塞
3.读返回0:当写端关闭,从管道中读数据,若管道中有数据,则读到数据
若管道中没有数据,read则返回0,不再阻塞
4.管道破裂:读端关闭,向管道中写入数据,发生管道破裂(异常)
void *memset(void *s,int c,size_t n)
(1)功能:将内存区域填充成指定的数据
(2)参数:s:要填充的空间首地址
c:要填充的字符
n:要填充的字节数
(3)返回值:成功:返回s的首地址
失败:NULL
单工:广播 半双工:对讲机 全双工:打电话
3.有名管道
(1)本质:内核空间的一段缓冲区,但这块缓冲区和一个管道文件相关联
(2)有名管道的操作流程:
1.创建管道文件 mkfifo,mkfifo()
2.打开管道文件 open()
3.写管道文件 write()
4.读管道文件 read()
5.关闭管道文件 close()
6.删除管道文件 int remove(const char *pathname)
int mkfifo(const char *pathname,mode_t mode)
(1)功能:创建一个管道文件
(2)参数:pathname:管道文件的名称
mode:管道文件的读写执行权限
(3)返回值:成功:0
失败:-1
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>int main(int argc, const char *argv[])
{int ret = mkfifo("./myfifo", 0664); if (ret != 0 && errno != EEXIST){perror("mkfifo error");return -1;}int fd = open("./myfifo", O_WRONLY);if (fd < 0){perror("open error");return -1;}write(fd, "hello world", 11);close(fd);//remove("./myfifo");return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>int main(int argc, const char *argv[])
{int ret = mkfifo("./myfifo", 0664);if (ret != 0 && errno != EEXIST){perror("mkfifo error");return -1;}int fd = open("./myfifo", O_RDONLY);if (fd < 0){perror("open error");return -1;}char buff[1024] = {0};ssize_t cnt = read(fd, buff, sizeof(buff));printf("cnt = %ld, buff = %s\n", cnt, buff);close(fd);remove("./myfifo");return 0;
}