我使用poll
来处理我的程序的各种文件描述符上的事件。每个连接都具有某些属性。它需要一个会话标识符和一个目标文件描述符(与poll
处理的fd分开)。
这是结构的样子:
typedef struct
{
struct pollfd pfd;
uint32_t session_id;
int target_fd;
} my_conn;
现在,poll
接受struct pollfd
个对象的数组。现在,my_conn*
当然会降级到struct pollfd*
,但由于poll
不接受指针数组,我不能简单地使用由第一个属性对齐的my_conn**
。
我最初的反应是遍历my_conn
数组并处理每个文件描述符,超时为零。
my_conn *conns = /* initialize connections*/ ;
size_t my_conn_count = /* number of connections */;
size_t i;
int cnt;
for(i = 0; i < my_conn_count; ++i)
{
cnt = poll(&conns[i].pfd, 1, 0);
if(cnt > 0)
{
// handle event
}
}
我的问题是:有没有更好的方法来处理具有其他属性的文件描述符?某种类型的map
会起作用,但似乎会占用更多内存。超时为0的poll
运行与poll
相比是否会显着降低多个文件描述符的性能?
答案 0 :(得分:4)
我的问题是:有没有更好的方法来处理文件描述符 有其他属性?
是。我将不得不付出巨大努力来设计一种可能更糟糕的方法。如果您要测试多个文件描述符,那么无论是在阻塞模式还是非阻塞模式下,它都会使poll()
无法单独轮询它们。关于您的具体提案,您可以更简单地通过从图片中删除poll()
并直接执行非阻塞I / O来实现同样的目标。
某种类型的地图可行,但它 似乎它会占用大量内存。
不一定。您已经有一个my_conn
数组。如果构造一个struct pollfd
的并行数组,则两者之间的索引直接对应。那么您可能不需要my_conn.pfd
成为struct pollfd
,因为它现在是外部的;您对该成员所需要的只是(int
)文件描述符本身 - 即使这样。因此,文件描述符可能会重复,但这就是它。这是我建议的解决问题的方法。
是否正在运行
poll
超时为0时,性能明显低于poll
一次多个文件描述符?
我不知道你的情况会有多明显,但功能调用是你可以做的最昂贵的事情之一。但它变得更糟。使用poll()
的典型应用程序在其周围放置一个循环,以便在任何给定时间保持向任何文件描述符准备的数据提供数据或从中读取数据。虽然我无法确定,但您似乎正在为此类事做好准备。如果这确实是它归结为什么,那么使用非阻塞poll
,无论是否一对一,使整个构造成为一个繁忙的循环,这是另一个事情poll()
旨在避免。