zoukankan      html  css  js  c++  java
  • Linux进程间通信(管道及有名管道FIFO)(转)

    一. 管道:

       1.只能用于具有亲缘关系的进程之间的通信  

       2.半双工通信模式

       3.一种特殊的文件,是一种只存在于内核中的读写函数

    管道基于文件描述符,管道建立时,有两个文件描述符:

    a. fd[0]: 固定用于读管道

    b. fd[1]: 固定用于写管道

    创建管道:pipe()

         一般步骤:1. pipe()创建管道  2. fork()创建子进程  3. 子进程会继承父进程的管道

    关闭管道:1. 逐个关闭文件描述符  2. close()

    eg. 父子进程间的管道通信:父子进程对管道分别有自己的读写通道,把无关的读端或写段关闭。

      

    View Code
     1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <string.h>
    4 #include <sys/types.h>
    5 #include <unistd.h>
    6
    7 #define MAX_DATA_LEN 256
    8 #define DELAY_TIME 1
    9
    10 int main() {
    11 pid_t pid;
    12 char buf[MAX_DATA_LEN];
    13 const char *data="Pipe Test program";
    14 int real_read,real_write;
    15 int pipe_fd[2];
    16
    17 memset((void*)buf,0,sizeof(buf));
    18
    19 if(pipe(pipe_fd)<0){
    20 perror("Pipe create error!\n");
    21 exit(1);
    22 }
    23
    24 if ((pid=fork())<0) {
    25 perror("Fork error!\n");
    26 exit(1);
    27 } else if (pid==0) {
    28 close(pipe_fd[1]);
    29 sleep(DELAY_TIME*3);
    30
    31 if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {
    32 printf("Child receive %d bytes from pipe: '%s'.\n",real_read,buf);
    33 }
    34
    35 close(pipe_fd[0]);
    36 exit(0);
    37 } else {
    38 close(pipe_fd[0]);
    39 sleep(DELAY_TIME);
    40
    41 if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {
    42 printf("Parent write %d bytes into pipe: '%s'.\n",real_write,data);
    43 }
    44
    45 close(pipe_fd[1]);
    46 waitpid(pid,NULL,0);
    47 exit(0);
    48 }
    49
    50 }

    二. 有名管道FIFO

      1. 使不相关的两个进程彼此通信:a. 通过路径名指出,在文件系统中可见  

                      b. 管道建立后,两进程可按普通文件一样对其操作

      2. FIFO遵循先进先出规则:a. 对管道读从开始处返回数据

                    b. 对管道写则把数据添加到末尾

                    c. 不支持如lseek()等文件定位操作

      创建有名管道:mkfifo()

    创建管道成功后,可使用open()、read()和write()等函数。
      为读而打开的管道可在open()中设置O_RDONLY
      为写而打开的管道可在open()中设置O_WRONLY
     
    与普通文件不同的是阻塞问题
      •普通文件的读写时不会出现阻塞问题
      •在管道的读写中却有阻塞的可能,
      •非阻塞标志:在open()函数中设定为O_NONBLOCK
     
    l阻塞打开与非阻塞打开
    对于读进程
      •若该管道是阻塞打开,且当前FIFO内没有数据,则对读进程而言将一直阻塞到有数据写入
      •若该管道是非阻塞打开,则不论FIFO内是否有数据,读进程都会立即执行读操作。即如果FIFO内没有数据,则读函数将立刻返回0
    对于写进程
      •若该管道是阻塞打开,则写操作将一直阻塞到数据可以被写入
      •若该管道是非阻塞打开而不能写入全部数据,则读操作进行部分写入或者调用失败
     
     
    eg. 写FIFO与读FIFO
    View Code
     1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <string.h>
    4 #include <sys/types.h>
    5 #include <sys/stat.h>
    6 #include <errno.h>
    7 #include <unistd.h>
    8 #include <fcntl.h>
    9
    10 #define FIFO "myfifo"
    11 #define BUFF_SIZE 1024
    12
    13 int main(int argc,char* argv[]) {
    14 char buff[BUFF_SIZE];
    15 int real_write;
    16 int fd;
    17
    18 if(argc<=1){
    19 printf("Usage: ./fifo_write string\n");
    20 exit(1);
    21 }
    22
    23 sscanf(argv[1],"%s",buff);
    24
    25 % 测试FIFO是否存在,若不存在,mkfifo一个FIFO
    26 if(access(FIFO,F_OK)==-1){
    27 if((mkfifo(FIFO,0666)<0)&&(errno!=EEXIST)){
    28 printf("Can NOT create fifo file!\n");
    29 exit(1);
    30 }
    31 }
    32
    33 % 调用open以只写方式打开FIFO,返回文件描述符fd
    34 if((fd=open(FIFO,O_WRONLY))==-1){
    35 printf("Open fifo error!\n");
    36 exit(1);
    37 }
    38
    39 % 调用write将buff写到文件描述符fd指向的FIFO中
    40 if ((real_write=write(fd,buff,BUFF_SIZE))>0) {
    41 printf("Write into pipe: '%s'.\n",buff);
    42 exit(1);
    43 }
    44
    45 close(fd);
    46 exit(0);
    47
    48 }
    View Code
     1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <string.h>
    4 #include <sys/types.h>
    5 #include <sys/stat.h>
    6 #include <errno.h>
    7 #include <unistd.h>
    8 #include <fcntl.h>
    9
    10 #define FIFO "myfifo"
    11 #define BUFF_SIZE 1024
    12
    13 int main() {
    14 char buff[BUFF_SIZE];
    15 int real_read;
    16 int fd;
    17
    18 %access确定文件或文件夹的访问权限。即,检查某个文件的存取方式
    19 %如果指定的存取方式有效,则函数返回0,否则函数返回-1
    20 %若不存在FIFO,则创建一个
    21 if(access(FIFO,F_OK)==-1){
    22 if((mkfifo(FIFO,0666)<0)&&(errno!=EEXIST)){
    23 printf("Can NOT create fifo file!\n");
    24 exit(1);
    25 }
    26 }
    27
    28 %以只读方式打开FIFO,返回文件描述符fd
    29 if((fd=open(FIFO,O_RDONLY))==-1){
    30 printf("Open fifo error!\n");
    31 exit(1);
    32 }
    33
    34 % 调用read将fd指向的FIFO的内容,读到buff中,并打印
    35 while(1){
    36 memset(buff,0,BUFF_SIZE);
    37 if ((real_read=read(fd,buff,BUFF_SIZE))>0) {
    38 printf("Read from pipe: '%s'.\n",buff);
    39 }
    40 }
    41
    42 close(fd);
    43 exit(0);
    44 }


     
     
  • 相关阅读:
    基于蓝牙的安卓客户端开发
    在word文档中添加上角标和下角标
    vs2008打开类视图,看不到类的解决方法
    容器vector 迭代器iterator 应用
    next_permutation()
    pair运用
    vector学习
    容器之vector
    指针 * &
    派生类中的构造函数和析构函数
  • 原文地址:https://www.cnblogs.com/forstudy/p/2412415.html
Copyright © 2011-2022 走看看