http://blog.csdn.net/yyyiran/article/details/19008063
http://blog.csdn.net/liuxuejiang158blog/article/details/26154893
管道和FIFO作为最初的UNIX IPC形式,现在已用得较少。SocketPair可作为全双工版本的管道,较为常用,这里简单做个笔记
管道
* 只用于有亲缘关系的进程间通信
* 单向,即半双工 (双向方法:1 使用2个管道 2 使用SocketPair)
* pipe() => write()/read()
FIFO (有名管道)
* 可用于无亲缘关系的进程间通信
* 单向
* mkfifo() => open() => write()/read()
SocketPair
* 套接字(一般用于网络通讯)提供的一种用于本机进程间通信方式
* 双向,即全双工
* socketpair() => write()/read()
* 例子 [ SocketPair.cpp ]:
[cpp] view plain copy print ?
- #include <iostream>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- using namespace std;
- const int MAXSIZE = 100;
-
- int main()
- {
- int fd[2];
- int rLen;
- char wBuf[MAXSIZE] ="Hello World";
- char rBuf[MAXSIZE];
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0)
- {
- cout << "SocketPair Err" << endl;
- return -1;
- }
-
- pid_t pid = fork();
- if (pid < 0)
- {
- cout << "Fork Err" << endl;
- return -1;
- }
-
- if (pid == 0)
- {
-
- cout << "Child, Pid=" << getpid() << endl;
- write(fd[0], wBuf, strlen(wBuf));
- write(fd[1], wBuf, strlen(wBuf));
- exit(-1);
- }
-
-
- sleep(1);
- cout << "Parent, Pid=" << getpid() << endl;
- rLen = read(fd[1], rBuf, MAXSIZE);
- rBuf[rLen] = 0;
- cout << "Read Fd[1], rBuf : " << rBuf << endl;
- rLen = read(fd[0], rBuf, MAXSIZE);
- rBuf[rLen] = 0;
- cout << "Read Fd[0], rBuf : " << rBuf << endl;
- return 0;
- }
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
using namespace std;
const int MAXSIZE = 100;
int main()
{
int fd[2];
int rLen;
char wBuf[MAXSIZE] = "Hello World";
char rBuf[MAXSIZE];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0)
{
cout << "SocketPair Err" << endl;
return -1;
}
pid_t pid = fork();
if (pid < 0)
{
cout << "Fork Err" << endl;
return -1;
}
if (pid == 0)
{
// Chlid
cout << "Child, Pid=" << getpid() << endl;
write(fd[0], wBuf, strlen(wBuf));
write(fd[1], wBuf, strlen(wBuf));
exit(-1);
}
// Parent
sleep(1);
cout << "Parent, Pid=" << getpid() << endl;
rLen = read(fd[1], rBuf, MAXSIZE);
rBuf[rLen] = 0;
cout << "Read Fd[1], rBuf : " << rBuf << endl;
rLen = read(fd[0], rBuf, MAXSIZE);
rBuf[rLen] = 0;
cout << "Read Fd[0], rBuf : " << rBuf << endl;
return 0;
}
[cpp] view plain copy print ?
- # g++ SocketPair.cpp
- # ./a.out
- Child, Pid=9569
- Parent, Pid=9568
- Read Fd[1], rBuf : Hello World
- Read Fd[0], rBuf : Hello World
domain只能为AF_UNIX,也就是限制在本地使用
type可以是SOCK_STREAM或SOCK_DGRAM,SOCK_STREAM相当于创建了双向流管道,管道的每一端都可以write或read,并且两端的数据流对流是分开的
protocol必须是0
sockfd数组返回管道两端的socket描述符
在2.6.27的内核版本后,type支持了SOCK_CLOEXEC(close on exec )和SOCK_NONBLOCK(非阻塞系统描述符)标志,以节省fcntl系统调用
socketpair创建的描述符常用于亲缘进程间通信,如父进程调用了socketpair后,父进程再调用fork出子进程,子进程自动继承了描述符(前提是没有close on exec),那么父子进程就可以用sockfd进行通信。
例子,父进程在sockepair后,再fork出子进程