1. 进程间通信
1. 管道
- 如果要进行全双工通信,需要建立两个管道
- 管道没有名字,传送的事无格式的字节流,大小受限制
- 在include/linux/limits.h中规定
#define PIPE_BUF 4096
, 也就是一次管道读写最多传送512字节 read(int _fd, void* buf, size_t _nbytes);
//读成功返回实际读取的字节数,失败返回-1,读到末端返回0,读空管道会被阻塞
write(INT _fd, _const void* _buff, size_t _n)
;//每次写的内容都附加在管道末端。为了避免交叉写入,每次写入的数据小于PIPE_BUF的大小
- 如果
O_NONBLOCK
和O_NDELAY
表示被清除时,出现设备忙的情况,write会导致进程阻塞,成功返回写入字节数 - 如果设置了这两个标识当数据没有写入成功时直接返回-1
1.管道
- pipe: 一种半双工通信方式,数据只能单向流动,只能在具有亲缘关系(父子进程关系)的进程间使用。
#include <unistd.h>
int pipe(int fd[2]);
- 如果进程要读取管道中的数据,应该关闭
fd[1]
,同理写关闭fd[0]
int fd[2];
if (pipe(fd)) {
cerr << "create pipe failure" << endl;
exit(1);
}
char message[100];
close(fd[1]);
read(fd[0], message, sizeof(message));
close(fd[0]);
write(fd[1], message, strlen(message)+1);
用管道联系标准设备
- 子进程中调用exec函数是,不能共享文件描述符。可以讲子进程中的文件描述符重定向到标准输入,当新执行程序从标准输入获取数据时实际上是从父进程中获取输入数据。
dup
和dup2
函数提供文件描述符复制功能- 复制的问键描述符回合原来的文件描述符共享同一个文件指针
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
pid = fork();
if (pid == 0) {
close(1);
dup[fd[1]);
execv("exam", argv, environ);
pid = fork();
if (pid == 0) {
dup2(1, fd[1]);
execv("exame", argv, environ);
}
2.有名管道
- named pipe: 同上,但是允许无亲缘关系进程间通信。
- shell 下使用
mknod namedpipe
创建一个有名管道 - 有名管道是一个设备文件
#include <sys/types.h>
#include <sys/stat.h>
int mknod(const char* path, mode_t mod, dev_t dev);
int mkfifo(const char* path, mode_t mod);
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define FIFO "/tmpt/fifo"
int main() {
pid_t pid;
char buffer[80];
int fd;
unlink(FIFO);
mkfifo(FIFO, 0744);
if ((pid = fork())>0) {
} else if (pid == 0) {
} else {
cerr << "fork" << endl;
exit(1);
}
return 0;
}
3.扩展
- POSIX2中用管道实现了简单的进程间通信函数
popen()
和pclose()
;
FILE* popen(_const char* _command, _const char* _modes);
#include <limits.h>
#include <sring.h>
int main(int argc, char* argv[]) {
FILE* finput, *foutput;
char* buffer(PIPE_BUF];
int n;
finput = popen("echo test!", "r");
fouput = popen("cat", "w");
read(fileno(finput), buffer, strlen("test"));
write(fileno(foutput), buffer, strlen("test"));
pclose(finput);
pclose(foutput);
return 0;
}