linux管道大小查看

2017-02-25 20:50:58 jyy305 阅读数 1847
  • Linux指令_管道命令

    1.Jeesite 4.0介绍与安装、 2.jeesite4.0 Eclipse 常用快捷键、 3.jeesite4.0文件结构与配置、 4.jeeiste4.0 内置模块与内置组件应用、 5.jeesite4.0代码生成器的应用、 6.jeesite4.0 Spring Boot快速入门、 7....

    158人学习 陈贺群
    免费试看

一.管道容量:我们通过ulimit -a命令查看到的pipo size定义的是内核管道缓冲区的大小,这个值的大小是由内核设定的;而pipe capacity指的是管道的最大值,即容量,是内核内存中的一个缓冲区。

1.首先我们通过命令来看一下内核管道缓冲区的大小:

2.我们可以通过一个程序来测试管道的最大容量

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<errno.h>
#include<signal.h>
int main()
{
 int pipefd[2];
 if(pipe(pipefd) < 0)
 {
  perror("pipe");
  return -1;
 }
 int ret;
 int size = 0;
 int flags = fcntl(pipefd[1], F_GETFL);
 fcntl(pipefd[1], F_SETFL, flags | O_NONBLOCK); // 设置为非阻塞 
 while (1) 
 {
  ret = write(pipefd[1], "c", 1); 
  if (ret < 0)
  {
   perror("write"); 
   break;
  }
  size++;
 }
  printf("size=%d\n", size);
  return 0; 
}

上述代码中fcntl()函数的相关解释

可以用fcntl 函数改变一个已打开的文件的属性,可以重新设置读、写、追加、非阻塞等标志

 参数 F_SETFL:对于filedes设置文件描述符标志。新标志值按第三个参数 (取为整型值)设置

  参数 F_GETFL: 对应于filedes 的文件状态标志作为函数值返回

 参数 O_NONBLOCK:设置为非阻塞。

二.管道的数据结构:在 Linux 中,管道的实现并没有使用专门的数据结构,而是借助了文件系统的file结构和VFS的索引节点inode。通过将两个 file 结构指向同一个临时的 VFS 索引节点,而这个 VFS 索引节点又指向一个物理页面而实现的。

2017-03-06 17:04:25 Dakuan_chen 阅读数 1097
  • Linux指令_管道命令

    1.Jeesite 4.0介绍与安装、 2.jeesite4.0 Eclipse 常用快捷键、 3.jeesite4.0文件结构与配置、 4.jeeiste4.0 内置模块与内置组件应用、 5.jeesite4.0代码生成器的应用、 6.jeesite4.0 Spring Boot快速入门、 7....

    158人学习 陈贺群
    免费试看

每一个进程都有各自独立的地址空间,热和一个进程都无法访问其他进程中的数据在,这样要实现进程间通信就要让两个进程能够看到一块公共的空间,这就是管道的原理。

管道有以下特点:

1:只能在有血缘关系的进程之间进行通信(也就是在父子进程之间通信)。

2:单向通信一个读端,一个写端,如果要双向通信就要建立两个管道。

3:接收数据流,与数据格式无关。

4:管道的生命周期随进程。

5:同步互斥原则。


管道是一种基本的IPC机制,由pipe()函数创建

#include<unistd.h>

pipe(int fileds[2])

fileds[0]是读端

fileds[1]是写段

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    int _pipe[2];
    if(pipe(_pipe)==-1)
    {
        printf("pipe error\n");
        return 1;
    }
    int ret;
    int count=0;
    int flag=fcntl(_pipe[1],F_GETFL);
    fcntl(_pipe[1],F_SETFL,flag|O_NONBLOCK);
    while(1)
    {
        ret=write(_pipe[1],"A",1);
        if(ret==-1)
        {
            printf("error %s\n",strerror(errno));
            break;
        }
        count++;
    }
    printf("count=%d\n",count);
    return 0;
}



所以管道的容量是64KB




2016-07-20 23:55:15 Footmart_C 阅读数 1758
  • Linux指令_管道命令

    1.Jeesite 4.0介绍与安装、 2.jeesite4.0 Eclipse 常用快捷键、 3.jeesite4.0文件结构与配置、 4.jeeiste4.0 内置模块与内置组件应用、 5.jeesite4.0代码生成器的应用、 6.jeesite4.0 Spring Boot快速入门、 7....

    158人学习 陈贺群
    免费试看

什么是管道

管道是Linux 支持的最初Unix IPC形式之一,具有以下特点:

  • 管道是半双工的,数据只能向一个方向流动;
  • 需要双方通信时,需要建立起两个管道;
  • 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);
  • 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在于内存中。
  • 数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

 

在Linux中,管道是一种使用非常频繁的通信机制。从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题,具体表现为:

限制管道的大小。实际上,管道是一个固定大小的缓冲区。在Linux中,该缓冲区的大小为1页,即4K字节,使得它的大小不象文件那样不加检验地增长。使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,当这种情况发生时,随后对管道的write()调用将默认地被阻塞,等待某些数据被读取,以便腾出足够的空间供write()调用写。

读取进程也可能工作得比写进程快。当所有当前进程数据已被读取时,管道变空。当这种情况发生时,一个随后的read()调用将默认地被阻塞,等待某些数据被写入,这解决了read()调用返回文件结束的问题。

注意:从管道读数据是一次性操作,数据一旦被读,它就从管道中被抛弃,释放空间以便写更多的数据。

 

实现机制:

管道是由内核管理的一个缓冲区,相当于我们放入内存中的一个纸条。管道的一端连接一个进程的输出。这个进程会向管道中放入信息。管道的另一端连接一个进程的输入,这个进程取出被放入管道的信息。一个缓冲区不需要很大,它被设计成为环形的数据结构,以便管道可以被循环利用。当管道中没有信息的话,从管道中读取的进程会等待,直到另一端的进程放入信息。当管道被放满信息的时候,尝试放入信息的进程会等待,直到另一端的进程取出信息。当两个进程都终结的时候,管道也自动消失。

 

从原理上,管道利用fork机制建立,从而让两个进程可以连接到同一个PIPE上。最开始的时候,上面的两个箭头都连接在同一个进程process1上(连接在process1上的两个箭头)。当fork复制进程的时候,会将这两个连接也复制到新的进程(process2)。随后,每个进程关闭自己不需要的一个连接 (两个黄色的箭头被关闭; process1关闭从PIPE来的输入连接,process2关闭输出到PIPE的连接),这样,剩下的黑色连接就构成了如上图的PIPE。

 

实现细节:

在 Linux 中,管道的实现并没有使用专门的数据结构,而是借助了文件系统的file结构和VFS的索引节点inode。通过将两个 file 结构指向同一个临时的 VFS 索引节点,而这个 VFS 索引节点又指向一个物理页面而实现的。如下图

 

有两个 file 数据结构,但它们定义文件操作例程地址是不同的,其中一个是向管道中写入数据的例程地址,而另一个是从管道中读出数据的例程地址。这样,用户程序的系统调用仍然是通常的文件操作,而内核却利用这种抽象机制实现了管道这一特殊操作。

 

判断当前计算机管道的容量

读端不读,写端一直写


 

 

 

https://www.ibm.com/developerworks/cn/linux/l-ipc/part1/

2017-03-03 13:54:44 scmuzi18 阅读数 1988
  • Linux指令_管道命令

    1.Jeesite 4.0介绍与安装、 2.jeesite4.0 Eclipse 常用快捷键、 3.jeesite4.0文件结构与配置、 4.jeeiste4.0 内置模块与内置组件应用、 5.jeesite4.0代码生成器的应用、 6.jeesite4.0 Spring Boot快速入门、 7....

    158人学习 陈贺群
    免费试看


管道容量(转自:http://blog.chinaunix.net/uid-27471192-id-3305880.html

  • 根据手册,linux上的PIPE容量为(capacity)65536个字节;实验得到ubuntu的PIPE_BUF为4096。这里要特别说明的是我看到网上有人将这个Capacity和PIPE_BUF混淆了, 管道的写端存在时,如果请求的字节数目大于PIPE_BUF,则返回管道中现有的数据字节数,如果请求的字节数目不大于PIPE_BUF,则返回管道中现 有数据字节数(此时,管道中数据量小于请求的数据量);或者返回请求的字节数(此时,管道中数据量不小于请求的数据量)PIPE_BUFinclude/linux/limits.h中定义,不同的内核版本可能会有所不同。Posix.1要求PIPE_BUF至少为512字节,red hat 7.2中为4096

  • 要保证write操作是原子操作,一次写入的字节数n就不能超过PIPE_BUF;非阻塞模式下当然还需要有>=n的空余空间,否则写入失败。一次写入大于PIPE_BUF的数据,不管是不是阻塞模式都不保证是原子操作

  • 非阻塞模式下,能一次性写入的最大数据量就是管道的容量即65536字节了,注意这里的一次性写入是指write不返回的情况下,和原子操作不是一回事。如果写入的更长,也只能写这么多,write函数会返回已写入的长度

  • 如果写端不存在,读的时候会返回0,代表读到了文件尾。如果读端不存在,写的时候就会产生SIGPIPE信号(忽略此信息的情况下write会返回失败,errno为EPIPE)

     

    linux终端输入*man 7 pipe*命令,可以查找到管道容量的最大和最小字节数

管道的实现机制:(转自:http://www.th7.cn/system/lin/201702/203314.shtml

管道是由内核管理的一个缓冲区,它的一端连接一个进程的输出,另一端连接一个进程的输入。管道的缓冲区不需要很大,它被设计为环形的数据结构,当两个进程都终止后,管道的生命周期也会被结束

从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题,具体表现为: 

管道是一个固定大小的缓冲区,在Linux中,该缓冲区的大小为一页,即4kb,使它的大小不会像普通文件那样不加检验的增长。在Linux中,内核使用struct pipe_inode_info结构体来描述一个管道,这个结构体定义在pipe_fs_i.h中。

struct pipe_inode_info结构体

 

缓冲区的个数:

#define PIPE_BUFFERS (16)

   管理缓冲区的结构

 

2017-03-09 17:54:57 qq_35116353 阅读数 7185
  • Linux指令_管道命令

    1.Jeesite 4.0介绍与安装、 2.jeesite4.0 Eclipse 常用快捷键、 3.jeesite4.0文件结构与配置、 4.jeeiste4.0 内置模块与内置组件应用、 5.jeesite4.0代码生成器的应用、 6.jeesite4.0 Spring Boot快速入门、 7....

    158人学习 陈贺群
    免费试看

ulimit  -a可以查看管道的大小,这是内核设定的为8*512byte=4k


LINUX 管道实现的机制

从本质上说,管道也是一种文件,但他又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题

   -  限制管道的大小。实际上,管道是一个固定大小的缓冲区。在Linux中该换冲区的大小为一页,4k

使得他的大小不像文件那样不加检验的增长。使用固定缓冲区也会带来问题,比如再写管道时可能变满

当这种情况发生时,随后对管道的write()调用被阻塞,等待某些数据被读取,以便腾出足够的空间供

write()调用。

   -  读取工作也可能比写的进程快。当所有进程的数据被读取完时,一个随后的read()调用将默认的被阻塞、

管道变空。这种情况发生时,一个随后的read()调用将被默认的阻塞,等待某些数据被写入,这样就解决了read()

调用将被默认的阻塞,等待某些数据将被写入,这解决了read()调用返回文件结束的问题。


写一个程序测试下管道容量



可以看到容量为65536


【Linux】Linux的管道

阅读数 20887

【Linux】管道

阅读数 551