Chinaunix首页 | 论坛 | 博客
  • 博客访问: 498807
  • 博文数量: 223
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2145
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-01 10:23
个人简介

该坚持的时候坚持,该妥协的时候妥协,该放弃的时候放弃

文章分类

全部博文(223)

文章存档

2017年(56)

2016年(118)

2015年(3)

2014年(46)

我的朋友

分类: LINUX

2014-11-15 19:47:39

第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]指向写端末尾

创建无名管道,并用于父子进程通讯
  1. #include <unistd.h>
  2. #include <stdio.h>

  3. void main()
  4. {
  5.     int pipefd[2];
  6.     int ret;
  7.     pid_t pid;
  8.     char buf[20];
  9.     
  10.     /*创建管道*/
  11.     ret = pipe(pipefd);
  12.     if(ret == -1)
  13.     {
  14.         printf("creat pipe failed.\n");
  15.         return;
  16.     }
  17.     
  18.     pid = fork();
  19.     if(pid > 0)
  20.     {
  21.         /*父进程写入数据*/
  22.         write(pipefd[1], "Hello", 6);
  23.         wait();
  24.         close(pipefd[1]);
  25.         exit(0);
  26.     }
  27.     else if(pid == 0)
  28.     {
  29.         /*子进程读取数据*/
  30.         if(read(pipefd[0], buf, 6) > 0)
  31.              printf("read buf is %s.\n",buf);
  32.         exit(0);
  33.     }
  34.     else
  35.     {
  36.         printf("creat process failed.\n");
  37.         return;
  38.     }

  39. }

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
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>
  5. #include <unistd.h>

  6. int main()
  7. {
  8.     int fd;

  9.     mkfifo("/tmp/myfifo",0666);

  10.     fd = open("/tmp/myfifo",O_WRONLY);

  11.     write(fd,"Hello World",12);

  12.     close(fd);
  13.     return 0;
  14. }
fifo-read.c
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <stdio.h>

  6. int main()
  7. {
  8.     int fd;
  9.     char buf[20];

  10.     fd = open("/tmp/myfifo",O_RDONLY);

  11.     read(fd,buf,15);
  12.     printf("read myfifo is %s.\n",buf);

  13.     close(fd);
  14.     unlink("/tmp/myfifo");
  15.     return 0;
  16. }

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差不多,就不详述了。
阅读(1181) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~