第5类 管道通讯编程类
一、通讯目的
1、数据传输
一个进程需要将数据发送给另一个进程。
2、资源共享
多个进程之间共享同样的资源。
3、通知事件
一个进程需要向另一个/组进程发送消息,通知它们发生了某事件。
4、进程控制
有些进程希望完全控制另一个进程的执行(如Debug进程),此时
控制进程希望能够拦截另一个进程的所有操作,并能够及时知道它
的状态改变。
二、通讯的发展
linux进程通信(
IPC:interprocess comnunication),由UNIX进程间通信、基于System V进程间通信、POSIX进程间通信几部分发展而来的。
POSIX:(Portable Operating System Interface)表示可移植操作系统接口,用来提高可移植性。
三、Linux进程通信方式
1、无名管道(pipe):数据传输
2、有名管道(FIFO):数据传输
3、信号(signal):事件通知
4、消息队列
5、共享内存
6、信号量:资源共享
7、套接字(socket)
四、无名管带只能用于父进程和子进程通信,有名管道可用于运行同一系统中的任意两个进程间的通信。
1)管道通信是单向的,有固定的读端和写端
2)数据被进程从管道读出后,在管道中该(取)数据就不存在了。
3)当进程去读取空管道的时候,进程会阻塞。(进程等待:读时空就等到写入、管道满了空出来才能写)
4)管道容量为64KB(#define PIPE_BUFFERS 16 include/linux/pipe_fs_i.h)
5.1 创建无名管道
5.1.1 函数名
pipe
5.1.2 函数原形
int pipe(int pipefd[2]);
5.1.3 函数功能
创建无名管道
5.1.4 所属头文件
unistd.h
5.1.5 返回值
成功:0 失败:-1
5.1.6 参数说明
Pipefd[2]:pipefd[0]指向读端末尾
Pipefd[1]指向写端末尾
创建无名管道,并用于父子进程通讯
-
#include <unistd.h>
-
#include <stdio.h>
-
-
void main()
-
{
-
int pipefd[2];
-
int ret;
-
pid_t pid;
-
char buf[20];
-
-
/*创建管道*/
-
ret = pipe(pipefd);
-
if(ret == -1)
-
{
-
printf("creat pipe failed.\n");
-
return;
-
}
-
-
pid = fork();
-
if(pid > 0)
-
{
-
/*父进程写入数据*/
-
write(pipefd[1], "Hello", 6);
-
wait();
-
close(pipefd[1]);
-
exit(0);
-
}
-
else if(pid == 0)
-
{
-
/*子进程读取数据*/
-
if(read(pipefd[0], buf, 6) > 0)
-
printf("read buf is %s.\n",buf);
-
exit(0);
-
}
-
else
-
{
-
printf("creat process failed.\n");
-
return;
-
}
-
-
}
5.2 创建有名管道
5.2.1 函数名
mkfifo
5.2.2 函数原形
int mkfifo(const char* pathname, mode_t mode);
5.2.3 函数功能
创建有名管道
5.2.4 所属头文件
sys/types.h sys/stat.h
5.2.5 返回值
success:0 error:-1
5.2.6 参数说明
pathname:要创建的fifo文件名
mode:fifo文件创建的标志权限
5.3 删除有名管道
5.3.1 函数名
unlink
5.3.2 函数原形
int unlink(const char *pathname);
5.3.3 函数功能
删除文件
5.3.4 所属头文件
stdio.h
5.3.5 返回值
success:0
error:-1
5.3.6 参数说明
pathname:用来指明要删除的文件名字(含路径)
fifo-write.c
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
-
#include <stdio.h>
-
#include <unistd.h>
-
-
int main()
-
{
-
int fd;
-
-
mkfifo("/tmp/myfifo",0666);
-
-
fd = open("/tmp/myfifo",O_WRONLY);
-
-
write(fd,"Hello World",12);
-
-
close(fd);
-
return 0;
-
}
fifo-read.c
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
-
#include <unistd.h>
-
#include <stdio.h>
-
-
int main()
-
{
-
int fd;
-
char buf[20];
-
-
fd = open("/tmp/myfifo",O_RDONLY);
-
-
read(fd,buf,15);
-
printf("read myfifo is %s.\n",buf);
-
-
close(fd);
-
unlink("/tmp/myfifo");
-
return 0;
-
}
fifo在写入后如果没有被读取,进程会被阻塞直到被读取后结束。
http://blog.csdn.net/nodeathphoenix/article/details/23357453
一、对于FIFO,需要open去打开FIFO的读端或是写端的描述符。
1> 如果open的时候没有指定O_NONBLOCK标志,且open的是读端时
如果不存在此FIFO的已经打开的写端时,open会一直阻塞到有FIFO的写端打开;
如果已经存在此FIFO的打开的写端时,open会直接成功返回。
2> 如果open的时候没有指定O_NONBLOCK标志,且open的是写端时
如果不存在此FIFO的已经打开的读端时,open会一直阻塞到有FIFO的读端打开;
如果已经存在此FIFO的打开的读端时,open会直接成功返回。
二、从FIFO或者空管道读写
1> read时,读端fd没有指定O_NONBLOCK标志
如果存在此FIFO或管道的已经打开的写端时,阻塞到FIFO或管道中有数据或者FIFO或管道的已经打开的写端全部被关闭为止。
如果不存在此FIFO或管道的已经打开的写端时,read返回0;
2> write时, 同read差不多,就不详述了。
阅读(1176) | 评论(0) | 转发(0) |