Chinaunix首页 | 论坛 | 博客
  • 博客访问: 82373
  • 博文数量: 18
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 85
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-18 09:53
文章分类
文章存档

2015年(18)

我的朋友

分类: LINUX

2015-05-14 14:23:09

1 无名管道,工作方式:半双工,即单项传输,无名管道局限性较大,只实现了有亲缘关系的进程进程间的通信,如下是简单的实现例子
涉及到的函数只有pipe(),其它的read(),write()为通用文件操作的系统调用.原型如下:
int pipe(int pipefd[2]);
简单测试代码如下:

点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <stdio.h>

  5. #include <errno.h>

  6. int main(int argc, char**argv)
  7. {
  8.     int pipe_fd[2];
  9.     pid_t child_pid;

  10.     char buf[100];

  11.     memset(buf, 0, sizeof(buf));

  12.     if (pipe(pipe_fd) < 0) {//创建管道,之后就读写就ok了
  13.         perror("pipe creat");
  14.         return -1;
  15.     }

  16.     if ( (child_pid = fork()) == -1) {
  17.         perror("fork()");
  18.     }

  19.     if (child_pid == 0) {//child
  20.         int w_ret = 0;
  21.         close(pipe_fd[0]);//管道只能一端读,一端写来实现自身功能,否则没意义0为读 1为写
  22.         while (1) {
  23.             strcpy(buf, "hello i am child");
  24.             w_ret = write(pipe_fd[1], buf, strlen(buf));//写操作
  25.             if (w_ret != -1) {
  26.                 printf("write\n");
  27.             } else {
  28.                 printf("write error....\n");
  29.             }
  30.             usleep(100000);
  31.         }
  32.         close(pipe_fd[1]);//理论上 不用时要关掉,这里拿来play
  33.     } else {//parent
  34.         int read_len = 0;
  35.         close(pipe_fd[1]);//关掉写端
  36.         while (1) {
  37.             read_len = read(pipe_fd[0], buf, 100);//读数据,读到怎么做,读不到怎么做等

  38.             printf("p->child pid %d read len %d: %s\n", child_pid, read_len, r_buf);
  39.     
  40.             usleep(500000);
  41.         }
  42.         close(pipe_fd[0]);//同上
  43.     }

  44.     return 0;
  45. }

2有名管道:有名管道克服了无名管道需要亲缘关系的缺点,所以个人觉得有名管道还是比较有用处的,它和管道一样,也是半双工,先进先出的方式。操作同样和文件类似,但是不支持想lseek等文件操作,严格的先进先出。
有名管道用到的函数:
int mkfifo(char *pathname, mode_t mode)
其中mode和open一样,而且有名管道创建之后也需要open,操作类似文件。
简单测试代码如下:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <errno.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <string.h>
  6. #include <sys/stat.h>

  7. #define FIFO_FILE "/tmp/testfifo"

  8. int getFifoFd(mode_t mode)//减少两个进程调用的公共代码, 创建管道和以mode的方式打开管道
  9. {
  10.     int fd;

  11.     if ((mkfifo(FIFO_FILE, O_CREAT | O_EXCL | 0600) < 0) && (errno != EEXIST)) {//创建管道
  12.         printf("creat: mkfifo error\n");
  13.     }

  14.     fd = open(FIFO_FILE, mode);//打开管道
  15.     if (fd < 0) {//
  16.         perror("open()");
  17.     }

  18.     return fd;
  19. }

  20. int main(int argc, char **argv)
  21. {
  22.     pid_t pid;
  23.     char buf[100];

  24.     memset(buf, 0, sizeof(buf));

  25.     if ((pid = fork()) < 0) {
  26.         perror("fork()");
  27.     } else if (pid == 0) {//child
  28.         int fd = getFifoFd(O_WRONLY);
  29.         
  30.         strcpy(buf, "hello write in child");

  31.         while (1) {
  32.             write(fd, buf, strlen("hello write in child"));

  33.             printf("write in child\n");

  34.             usleep(500000);
  35.         }
  36.     } else {//parent
  37.         int fd = getFifoFd(O_RDONLY);
  38.         int num;

  39.         usleep(1000000);
  40.         while (1) {
  41.             num = read(fd, buf, 100);
  42.             if (num > 0) {
  43.                 printf("%d read from buffer: %s\n", num, buf);
  44.             }

  45.             usleep(1000000);
  46.         }
  47.     }
  48.     
  49.     return 0;
  50. }



阅读(3956) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~