linux pipe 缓冲大小,linux下,pipe的容量的讨论与查看
1、pipe的容量
2.6標準版本的linux內核,pipe緩沖區是64KB,盡管命令ulimit -a看到管道大小8塊,緩沖區的大小不是4 k,因為內核動態分配最大16“緩沖條目”,乘64 k。這些限制是硬編碼的
2、如何查看自己pc上的pipe多大
1)通過ulimit -a查看到 pipe size?一次原子寫入為:512Bytes*8=4096Bytes
查看緩沖條目個數:cat /usr/src/kernels/3.10.0-327.el7.x86_64/include/linux/pipe_fs_i.h文件
所以我的pc下得pipe緩沖大小為:16*4096=65536Bytes
也就驗證了man 7 pipe下的pipe capacity
3、pipe的內部組織方式
在 Linux 中,管道的實現并沒有使用專門的數據結構,而是借助了文件系統的file結構和VFS的索引節點inode。通過將兩個 file 結構指向同一個臨時的 VFS 索引節點,而這個 VFS 索引節點又指向一個物理頁面而實現的。
有兩個 file 數據結構,但它們定義文件操作例程地址是不同的,其中一個是向管道中寫入數據的例程地址,而另一個是從管道中讀出數據的例程地址。這樣,用戶程序的系統調用仍然是通常的文件操作,而內核卻利用這種抽象機制實現了管道這一特殊操作。
cat /usr/src/kernels/3.10.0-327.el7.x86_64/include/linux/pipe_fs_i.h文件
#ifndef?_LINUX_PIPE_FS_I_H
#define?_LINUX_PIPE_FS_I_H
#define?PIPE_DEF_BUFFERS16
#define?PIPE_BUF_FLAG_LRU0x01/*?page?is?on?the?LRU?*/
#define?PIPE_BUF_FLAG_ATOMIC0x02/*?was?atomically?mapped?*/
#define?PIPE_BUF_FLAG_GIFT0x04/*?page?is?a?gift?*/
#define?PIPE_BUF_FLAG_PACKET0x08/*?read()?as?a?packet?*/
/**
*struct?pipe_buffer?-?a?linux?kernel?pipe?buffer
*@page:?the?page?containing?the?data?for?the?pipe?buffer
*@offset:?offset?of?data?inside?the?@page
*@len:?length?of?data?inside?the?@page
*@ops:?operations?associated?with?this?buffer.?See?@pipe_buf_operations.
*@flags:?pipe?buffer?flags.?See?above.
*@private:?private?data?owned?by?the?ops.
**/
struct?pipe_buffer?{
struct?page?*page;
unsigned?int?offset,?len;
const?struct?pipe_buf_operations?*ops;
unsigned?int?flags;
unsigned?long?private;
};
/**
*struct?pipe_inode_info?-?a?linux?kernel?pipe
*@mutex:?mutex?protecting?the?whole?thing
*@wait:?reader/writer?wait?point?in?case?of?empty/full?pipe
*@nrbufs:?the?number?of?non-empty?pipe?buffers?in?this?pipe
*@buffers:?total?number?of?buffers?(should?be?a?power?of?2)
*@curbuf:?the?current?pipe?buffer?entry
*@tmp_page:?cached?released?page
*@readers:?number?of?current?readers?of?this?pipe
*@writers:?number?of?current?writers?of?this?pipe
*@files:?number?of?struct?file?refering?this?pipe?(protected?by?->i_lock)
*@waiting_writers:?number?of?writers?blocked?waiting?for?room
*@r_counter:?reader?counter
*@w_counter:?writer?counter
*@fasync_readers:?reader?side?fasync
*@fasync_writers:?writer?side?fasync
*@bufs:?the?circular?array?of?pipe?buffers
**/
struct?pipe_inode_info?{
struct?mutex?mutex;
wait_queue_head_t?wait;
unsigned?int?nrbufs,?curbuf,?buffers;
unsigned?int?readers;
unsigned?int?writers;
unsigned?int?files;
unsigned?int?waiting_writers;
unsigned?int?r_counter;
unsigned?int?w_counter;
struct?page?*tmp_page;
struct?fasync_struct?*fasync_readers;
struct?fasync_struct?*fasync_writers;
struct?pipe_buffer?*bufs;
};
/*
*?Note?on?the?nesting?of?these?functions:
*
*?->confirm()
*->steal()
*...
*->map()
*...
*->unmap()
*
*?That?is,?->map()?must?be?called?on?a?confirmed?buffer,
*?same?goes?for?->steal().?See?below?for?the?meaning?of?each
*?operation.?Also?see?kerneldoc?in?fs/pipe.c?for?the?pipe
*?and?generic?variants?of?these?hooks.
*/
struct?pipe_buf_operations?{
/*
*?This?is?set?to?1,?if?the?generic?pipe?read/write?may?coalesce
*?data?into?an?existing?buffer.?If?this?is?set?to?0,?a?new?pipe
*?page?segment?is?always?used?for?new?data.
*/
int?can_merge;
/*
*?->map()?returns?a?virtual?address?mapping?of?the?pipe?buffer.
*?The?last?integer?flag?reflects?whether?this?should?be?an?atomic
*?mapping?or?not.?The?atomic?map?is?faster,?however?you?can't?take
*?page?faults?before?calling?->unmap()?again.?So?if?you?need?to?eg
*?access?user?data?through?copy_to/from_user(),?then?you?must?get
*?a?non-atomic?map.?->map()?uses?the?kmap_atomic?slot?for
*?atomic?maps,?you?have?to?be?careful?if?mapping?another?page?as
*?source?or?destination?for?a?copy.
*/
void?*?(*map)(struct?pipe_inode_info?*,?struct?pipe_buffer?*,?int);
/*
*?Undoes?->map(),?finishes?the?virtual?mapping?of?the?pipe?buffer.
*/
void?(*unmap)(struct?pipe_inode_info?*,?struct?pipe_buffer?*,?void?*);
/*
*?->confirm()?verifies?that?the?data?in?the?pipe?buffer?is?there
*?and?that?the?contents?are?good.?If?the?pages?in?the?pipe?belong
*?to?a?file?system,?we?may?need?to?wait?for?IO?completion?in?this
*?hook.?Returns?0?for?good,?or?a?negative?error?value?in?case?of
*?error.
*/
int?(*confirm)(struct?pipe_inode_info?*,?struct?pipe_buffer?*);
/*
*?When?the?contents?of?this?pipe?buffer?has?been?completely
*?consumed?by?a?reader,?->release()?is?called.
*/
void?(*release)(struct?pipe_inode_info?*,?struct?pipe_buffer?*);
/*
*?Attempt?to?take?ownership?of?the?pipe?buffer?and?its?contents.
*?->steal()?returns?0?for?success,?in?which?case?the?contents
*?of?the?pipe?(the?buf->page)?is?locked?and?now?completely?owned
*?by?the?caller.?The?page?may?then?be?transferred?to?a?different
*?mapping,?the?most?often?used?case?is?insertion?into?different
*?file?address?space?cache.
*/
int?(*steal)(struct?pipe_inode_info?*,?struct?pipe_buffer?*);
/*
*?Get?a?reference?to?the?pipe?buffer.
*/
void?(*get)(struct?pipe_inode_info?*,?struct?pipe_buffer?*);
};
/*?Differs?from?PIPE_BUF?in?that?PIPE_SIZE?is?the?length?of?the?actual
memory?allocation,?whereas?PIPE_BUF?makes?atomicity?guarantees.??*/
#define?PIPE_SIZEPAGE_SIZE
/*?Pipe?lock?and?unlock?operations?*/
void?pipe_lock(struct?pipe_inode_info?*);
void?pipe_unlock(struct?pipe_inode_info?*);
void?pipe_double_lock(struct?pipe_inode_info?*,?struct?pipe_inode_info?*);
extern?unsigned?int?pipe_max_size,?pipe_min_size;
int?pipe_proc_fn(struct?ctl_table?*,?int,?void?__user?*,?size_t?*,?loff_t?*);
/*?Drop?the?inode?semaphore?and?wait?for?a?pipe?event,?atomically?*/
void?pipe_wait(struct?pipe_inode_info?*pipe);
struct?pipe_inode_info?*alloc_pipe_info(void);
void?free_pipe_info(struct?pipe_inode_info?*);
/*?Generic?pipe?buffer?ops?functions?*/
void?*generic_pipe_buf_map(struct?pipe_inode_info?*,?struct?pipe_buffer?*,?int);
void?generic_pipe_buf_unmap(struct?pipe_inode_info?*,?struct?pipe_buffer?*,?void?*);
void?generic_pipe_buf_get(struct?pipe_inode_info?*,?struct?pipe_buffer?*);
int?generic_pipe_buf_confirm(struct?pipe_inode_info?*,?struct?pipe_buffer?*);
int?generic_pipe_buf_steal(struct?pipe_inode_info?*,?struct?pipe_buffer?*);
void?generic_pipe_buf_release(struct?pipe_inode_info?*,?struct?pipe_buffer?*);
/*?for?F_SETPIPE_SZ?and?F_GETPIPE_SZ?*/
long?pipe_fcntl(struct?file?*,?unsigned?int,?unsigned?long?arg);
struct?pipe_inode_info?*get_pipe_info(struct?file?*file);
int?create_pipe_files(struct?file?**,?int);
#endif
將上面的文件進行提取重要的結構
//inode結點信息結構
struct?inode?{
...
struct?pipe_inode_info??*i_pipe;
...
};
//管道緩沖區個數
#define?PIPE_BUFFERS?(16)
//管道緩存區對象結構
struct?pipe_buffer?{
struct?page?*page;?//管道緩沖區頁框的描述符地址
unsigned?int?offset,?len;?//頁框內有效數據的當前位置,和有效數據的長度
struct?pipe_buf_operations?*ops;?//管道緩存區方法表的地址
};
//管道信息結構
struct?pipe_inode_info?{
wait_queue_head_t?wait;?//管道等待隊列
unsigned?int?nrbufs,?curbuf;
//包含待讀數據的緩沖區數和包含待讀數據的第一個緩沖區的索引
struct?pipe_buffer?bufs[PIPE_BUFFERS];?//管道緩沖區描述符數組
struct?page?*tmp_page;?//高速緩存區頁框指針
unsigned?int?start;??//當前管道緩存區讀的位置
unsigned?int?readers;?//讀進程的標志,或編號
unsigned?int?writers;?//寫進程的標志,或編號
unsigned?int?waiting_writers;?//在等待隊列中睡眠的寫進程的個數
unsigned?int?r_counter;?//與readers類似,但當等待寫入FIFO的進程是使用
unsigned?int?w_counter;?//與writers類似,但當等待寫入FIFO的進程時使用
struct?fasync_struct?*fasync_readers;?//用于通過信號進行的異步I/O通知
struct?fasync_struct?*fasync_writers;?//用于通過信號的異步I/O通知
};
總結
以上是生活随笔為你收集整理的linux pipe 缓冲大小,linux下,pipe的容量的讨论与查看的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何留住新员工
- 下一篇: “企业级零代码黑客马拉松大赛”决赛名单公