Linux进程间通信之管道
进程间通信 (IPC ) Inter-Process Communication
比较好理解概念的就是进程间通信就是在不同进程之间传播或交换信息。
linux下IPC机制的分类
管道、信号、共享内存、消息队列、信号量、套接字
特点
- 管道是最古老的IPC,但目前很少使用
- 以文件做交互的媒介,管道分为有名管道和无名管道
- 历史上的管道通常是指半双工管道,如果需要双向通信,则创建两个管道
3.2 管道:有两种形式,命令行和非命令行
编程模型:进程A创建管道(mkfifo) -> 进程A写打开管道(open) -> 进程B读打开管道(open) -> 进程A开始往管道里写数据(write) ->
进程B从管道中读数据(read) -> 进程A关闭管道(close) -> 进程B关闭管道(close) -> 删除管道(unlink)
有名管道(实例):
Server:
#include <iostream>
#include<sys/stat.h>
#include<fcntl.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
#define PIPEWRITENAME "/home/qgm/pipeWriteServer"
#define PIPEREADNAME "/home/qgm/pipeReadServer"
void *readFun(void *arg)
{
//删除管道
unlink(PIPEREADNAME);
// 创建管道
if(mkfifo(PIPEREADNAME, 0666) < 0)
{
perror("mkfifo");
return (void*)-1;
}
// 写打开管道
int fd = open(PIPEREADNAME, O_RDWR);
if(-1 == fd)
{
perror("open");
return (void*)-1;
}
int i = 0;
for(i = 0; i < 100000; i++)
{
int n = 0;
read(fd, &n, sizeof(n));
printf("server read %d\n", n);
sleep(1); // 这个是以秒为单位挂起
}
// 关闭管道
close(fd);
return (void *)0;
}
void *writeFun(void *arg)
{
//删除管道
unlink(PIPEWRITENAME);
// 创建管道
if(mkfifo(PIPEWRITENAME, 0666) < 0)
{
perror("mkfifo");
return (void*)-1;
}
// 写打开管道
int fd = open(PIPEWRITENAME, O_RDWR);
if(-1 == fd)
{
perror("open");
return (void*)-1;
}
int i = 0;
for(i = 0; i < 100000; i++)
{
write(fd, &i, sizeof(i));
printf("server write %d\n", i);
sleep(1); // 这个是以秒为单位挂起
}
// 关闭管道
close(fd);
return (void *)0;
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, writeFun, NULL);
pthread_create(&tid, NULL, readFun, NULL);
sleep(100000);
return 0;
}
client:
#include <iostream>
#include<sys/stat.h>
#include<fcntl.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
#define PIPEWRITENAME "/home/qgm/pipeWriteServer"
#define PIPEREADNAME "/home/qgm/pipeReadServer"
void *readFun(void *arg)
{
// 写打开管道
int fd = open(PIPEWRITENAME, O_RDONLY);
if(-1 == fd)
{
perror("open");
return (void*)-1;
}
int i = 0;
for(i = 0; i < 100000; i++)
{
int n = 0;
read(fd, &n, sizeof(n));
printf("client read %d\n", n);
sleep(1); // 这个是以秒为单位挂起
}
// 关闭管道
close(fd);
return (void *)0;
}
void *writeFun(void *arg)
{
// 写打开管道
int fd = open(PIPEREADNAME, O_RDWR);
if(-1 == fd)
{
perror("open");
return (void*)-1;
}
int i = 0;
for(i = 0; i < 100000; i++)
{
write(fd, &i, sizeof(i));
printf("client write %d\n", i);
sleep(1); // 这个是以秒为单位挂起
}
// 关闭管道
close(fd);
return (void *)0;
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, readFun, NULL);
pthread_create(&tid, NULL, writeFun, NULL);
sleep(100000);
return 0;
}
注意:管道的数据长度为64K,所以使用的时候需要注意