利布代夫如何将轮询与文件描述符一起使用
libudev how to use poll with the file descriptor
所以,我有一个应用程序,我想在 Linux 上收到热插拔事件的通知。自然,我查看了libudev及其API。我还找到了一个关于如何在 libudev 中使用 select() 的有用教程。按照教程并浏览 API,我想出了这个示例程序,该程序等待热插拔事件,然后输出有关刚刚添加或删除的设备的一些基本信息。
#include <poll.h>
#include <libudev.h>
#include <stdexcept>
#include <iostream>
udev* hotplug;
udev_monitor* hotplug_monitor;
void init()
{
// create the udev object
hotplug = udev_new();
if(!this->hotplug)
{
throw std::runtime_error("cannot create udev object");
}
// create the udev monitor
hotplug_monitor = udev_monitor_new_from_netlink(hotplug, "udev");
// start receiving hotplug events
udev_monitor_enable_receiving(hotplug_monitor);
}
void deinit()
{
// destroy the udev monitor
udev_monitor_unref(hotplug_monitor);
// destroy the udev object
udev_unref(hotplug);
}
void run()
{
// create the poll item
pollfd items[1];
items[0].fd = udev_monitor_get_fd(hotplug_monitor);
items[0].events = POLLIN;
items[0].revents = 0;
// while there are hotplug events to process
while(poll(items, 1, 50) > 0)
{
// XXX
std::cout << "hotplug[ " << items[0].revents << " ]" << std::endl;
// receive the relevant device
udev_device* dev = udev_monitor_receive_device(hotplug_monitor);
if(!dev)
{
// error receiving device, skip it
continue;
}
// XXX
std::cout << "hotplug[" << udev_device_get_action(dev) << "] ";
std::cout << udev_device_get_devnode(dev) << ",";
std::cout << udev_device_get_subsystem(dev) << ",";
std::cout << udev_device_get_devtype(dev) << std::endl;
// destroy the relevant device
udev_device_unref(dev);
// XXX
std::cout << "done" << std::endl;
// clear the revents
items[0].revents = 0;
}
}
int main(int args, char* argv[])
{
init();
while(true)
{
run();
}
deinit();
}
好吧,它不起作用。这是我插入 USB 鼠标时得到的输出。
hotplug[ 1 ]
hotplug[add] /dev/bus/usb/008/002,usb,usb_device
done
hotplug[ 1 ]
hotplug[add]
此时程序冻结,我必须使用 Ctrl-C 停止它。我做错了什么?
程序实际上并没有停止;它继续运行,但是当你尝试打印一个 NULL 字符串时,std::cout 会搞砸(并非所有事件都有所有属性)。解决方法是使三个打印(devnode,子系统,devtype)有条件。
相关文章:
- 使用VerQueryValue检索应用程序的文件描述
- 如何在C/C++中用FD_set Unix设置套接字文件描述符
- I2C 文件描述符上的 I2C 总线可写/可读标志
- 许多文件描述符在调用sys_clone时
- AMQP-CPP >处理程序中的错误文件描述符
- 如何使用 WINAPI 和 C++ 提取可执行文件的文件描述?
- 正在等待在非阻塞文件描述符上长时间运行ioctl
- 有没有适用于Windows.lib文件的GNU二进制文件描述符(BFD)
- 如何强制文件描述符缓冲我的输出
- 如何从 boost::asio::ssl::stream<boost::asio::ip::tcp::socket> 获取本机套接字文件描述器?
- 哪个更适合从C++写入敏感的日志文件,在文件描述符上写()或文件上的fprintf()?
- 将 select() 与非基于文件描述符的输入一起使用
- accept(..) 似乎正在修改我给它的文件描述符参数
- 使用 Select 多路复用未命名的管道和其他文件描述符
- 提升 ASIO 绑定:错误的文件描述符
- 使用文件描述符移动对象
- 无法从零MQ ZMQ_SERVER套接字中获取文件描述符
- read() 上的不同行为取决于写入不可写内存时表示文件、匿名管道或套接字的文件描述符
- 我是否需要在使用它的 R 包的描述文件中导入 RccpEigen,或者"LinkingTo"足够?
- GCC链接器描述文件强制符号位于特定地址