【发布时间】:2020-12-04 19:27:55
【问题描述】:
我正在编写用户空间应用程序,其中包括使用netlink 套接字与内核通信的其他功能。我使用开源库libmnl提供的简单API。
我的应用程序在 netlink 上设置了某些选项,并订阅了 netlink 事件(通知),解析它等。所以第二个功能(事件通知)是异步的,目前我实现了一个简单的基于 select() 的循环:
...
fd_set rfd;
struct timeval tv;
int ret;
while (1) {
tv.tv_sec = 1;
tv.tv_usec = 0;
FD_ZERO(&rfd);
/* fd - is a netlink socket */
FD_SET(fd, &rfd);
ret = select(fd + 1, &rfd, NULL, NULL, &tv);
if (ret < 0) {
perror("select()");
continue;
} else if (ret == 0) {
printf("Timeout on fd %d", fd);
} else if (FD_ISSET(fd, &rfd)) {
/*
count = recv(fd, buf ...)
while (count > 0) {
parse 'buf' for netlink message, validate etc.
count = recv(fd, buf)
}
*/
}
}
所以我现在观察到 else if (FD_ISSET(fd, &rfd)) { 分支内的代码在第二次 recv() 调用时阻塞。
现在我想了解是否需要将 netlink 套接字设置为非阻塞(例如 SOCK_NOBLOCK),但我可能根本不需要 select(),我只需 @987654330 @循环,它不会阻塞。
【问题讨论】:
-
如果你不使用
select(),你的代码将在一个紧密的循环中运行,不断调用recv()并得到EWOULDBLOCK错误,除非你在循环中插入一个sleep。 -
阻塞是有原因的——没有数据可以接收。您当然可以使套接字不阻塞,但是您希望达到什么结果?您将不得不返回并再次调用
recv,直到有数据或有处理无数据情况的逻辑。所以这是否是正确的做法取决于期望的行为是什么。 -
这能回答你的问题吗? socket select ()versus non-block recv 和 several others.
-
在阻塞模式下使用
select()没有多大意义。你也可以直接屏蔽recv()。
标签: linux sockets select nonblocking netlink