Linux 中的异步套接字——轮询与回调通过

Posted

技术标签:

【中文标题】Linux 中的异步套接字——轮询与回调通过【英文标题】:Asynchronous Sockets in Linux-- Polling vs. Callback via 【发布时间】:2012-05-01 15:07:17 【问题描述】:

在决定在我的简单服务器 (linux) 中实现异步套接字时,我遇到了一个问题。我打算不断地 poll(),并在调用之间进行一些清理和缓存。现在这似乎很浪费,所以我做了更多的挖掘并找到了一种方法来可能在 i/o 上实现一些回调。

如果我使用 O_NONBLOCK 创建一个套接字,使用 SIOCSPGRP ioctl() 在 i/o 上发送 SIGIO,并使用 sigaction() 在输入输出。

另外,我可以为不同的socket定义不同的函数吗?

【问题讨论】:

你为什么不看看libeventlibev之类的东西? 我正在尝试尽可能使用裸组件^^ 我曾经尝试过这个(并且成功了!)但是生成的程序花费了 80% 的时间来修补 sigprocmask。关键是:您不能在信号处理程序中调用 malloc() ,因此您必须在禁用 SIGIO 的情况下进行预分配。普通的 select() 或 poll() 循环(可能带有线程)可能更容易管理。供参考:IIRC NTP 使用 SIGIO。可能 DNS/bind 也会这样做,不知道。 【参考方案1】:

“我打算不断地 poll(),并在调用之间做一些清理和缓存。现在这似乎很浪费”

浪费怎么办?您是否真的尝试过实现它?

你有你的 fd 列表。您可以使用列表调用 poll 或(更好)epoll()。当它触发时,你遍历 fd 列表并适当地处理每一个。您需要缓存传入和传出数据,因此每个 fd 都需要某种结构。完成此操作后,我为 fd 结构使用了哈希表(从 fd 生成密钥),但您可能没问题,至少最初,只需使用固定长度的数组并检查操作系统是否向您发出了一个奇怪的高 fd(nb,我从未见过这种情况发生,我眯着眼睛看的日志比我能数的要多)。结构体持有指向传入和传出缓冲区的指针,可能是一个状态变量,例如:

struct connection 
   int fd;  // mandatory for the hash table version
   unsigned char *dataOut;
   unsigned char *dataIn;
   int state;  // probably from an enum
;

struct connection connected[1000];  // your array, or...

...可能链表实际上最适合 fd,我对哈希表有一个不相关的要求。

从那里开始并逐步完善。我认为你只是想找到一个简单的出路——你可能会在以后通过让其他事情变得更困难来支付费用;)0.02 美元。

【讨论】:

使用回调的目的是让我可以将更多时间用于资源管理、内存碎片整理(我也在实现自己的 malloc)。我不确定何时应该停止轮询并开始维护。我不想错过连接,因为我的服务器正忙于弄清楚我可以移动什么来释放内存;p 我想我只是不确定如何进行调度,所以实现某种回调可以提供一个办法。另外,我试图远离线程。 (我之前和他们一起工作过,我只是想尝试在一个线程/进程中拥有它) 我怀疑通过回调中断 mm 例程然后处理连接是否会让生活更轻松。编写例程,以便他们一次做一点,经常做。这符合异步模型。为空闲时的轮询设置适当的超时。当 poll() 返回时,在处理内容的 fd 列表的末尾,您检查是否是时候运行一些快速的 mm 内容,然后再循环并再次调用 poll()。那时,如果服务器很忙,您只是将一堆东西传递给 OS 套接字层供其处理;这是做你(快速)mm的最佳时机。 您还可以根据 poll() 返回时 fd 列表的情况来确定服务器是否空闲(或者,提出“有多忙”的指标),并使用它来确定在该周期结束时,多少(如果有)毫米的东西是合适的。基本上,我认为您应该考虑如何将 mm 与套接字处理集成,而不是将它们视为单个进程的两个完全不相关且独立的活动。否则,线程。 “怎么浪费?” - 好吧,我相信首选的方法是让线程休眠,直到有工作要做。轮询只是旋转,因此线程正在消耗 CPU 周期。这些 CPU 周期可以用于其他 [有用的] 工作,因此轮询和旋转是一种浪费。 @noloader poll() 如果无事可做,则不会“只是旋转”。这是一种被动的等待。阻塞调用。阅读手册页。如果您认为检查是否有 mm 每 30 秒执行一次 而服务器仍处于空闲状态 代表“浪费 CPU 周期”,那么您就输了。它与您将要获得的方法一样便宜...当服务器不空闲时是的,poll() 会旋转,大声笑,您还要如何管理套接字?

以上是关于Linux 中的异步套接字——轮询与回调通过的主要内容,如果未能解决你的问题,请参考以下文章

轮询与 AsyncCallback 回调 - 慢速 Web 服务的最佳方法?

处理异步套接字(.Net)后仍然会调用回调

异步事件:轮询与中断

套接字对、perl、KEEPALIVE 和轮询

在所有异步套接字回调上强制线程 CultureInfo

TCP 客户端异步套接字回调