首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何缓冲非阻塞IO?

如何缓冲非阻塞IO?
EN

Stack Overflow用户
提问于 2009-03-12 10:07:04
回答 5查看 3.4K关注 0票数 4

当我需要阻塞文件描述符上的缓冲IO时,我使用stdio。但是,如果我按照手动的方式将文件描述符转换为非阻塞模式,那么stdio缓冲就无法使用。经过一些研究,我发现BIO可以用于缓冲非阻塞IO。

但也许还有其他选择呢?

为了避免在多连接环境中使用线程,我需要这样做。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-04-30 19:26:48

我想你说的是Reactor Pattern。这是在没有线程的情况下处理大量网络连接的非常标准的方法,并且在多人游戏服务器引擎中非常常见。另一个实现(在python中)是twisted matrix

基本算法是:

  • 为每个套接字提供一个缓冲区
  • 检查哪些套接字已准备好读取(select()、poll()或只是迭代)
  • 为每个套接字调用recv()并将内容累积到套接字的缓冲区中,直到recv返回0或套接字的buffer

的应用程序级数据处理程序出错<>H113清除套接字的代码

票数 15
EN

Stack Overflow用户

发布于 2009-03-13 11:09:46

我看到这个问题现在已经被编辑过了,至少比以前更容易理解。

无论如何,这不是一个矛盾的问题吗?

  • 您将I/O设为非阻塞是因为您希望能够快速读取少量数据,通常会牺牲吞吐量来换取延迟。
  • 您将I/O设置为缓冲是因为您不太关心延迟,但希望通过牺牲延迟来换取吞吐量来有效地利用I/O子系统。

同时做这两件事似乎是矛盾的,很难想象。

你想要的语义是什么?如果您这样做:

代码语言:javascript
复制
int     fd;
char    buf[1024];
ssize_t got;

fd = setup_non_blocking_io(...);
got = read(fd, buf, sizeof buf);

如果有3个字节可用,你预计会有什么行为?阻塞/缓冲的I/O可能会阻塞,直到能够读取更多满足您的请求,非阻塞I/O将立即返回3个可用字节。

当然,如果你在上面有一些协议,它定义了某种类型的消息结构,这样你就可以知道“这个I/O是不完整的,我不能解析它,直到我有更多的数据”,你可以自己在那个级别缓冲它,并且在收到完整的消息之前不会向上传递数据。

票数 3
EN

Stack Overflow用户

发布于 2009-05-06 11:47:59

根据协议的不同,您肯定可能需要为非阻塞网络节点(客户端或服务器)缓冲读取。

通常,这些缓冲区提供多个索引(偏移量),记录处理的最后一个字节和读取的最后一个字节的位置(等于或大于处理的偏移量)。并且它们还(应该)提供压缩缓冲区、透明缓冲区大小管理等更丰富的语义。

在Java语言中(至少),非阻塞网络io (NIO)包还提供了一组数据结构(ByteBuffer等)。它们适合于提供通用的数据结构。

对于C,要么存在这样的数据结构,要么你必须使用自己的数据结构。一旦您有了它,那么只需读取尽可能多的数据,并让缓冲区管理溢出等问题(例如,跨消息帧边界读取字节),并使用标记偏移量来标记您已处理的字节。

正如Android指出的,您将(很可能)需要为每个打开的连接创建匹配的缓冲区。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/637964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档