如何将“select”移植到“poll”以获取第三个错误数据?

问题描述 投票:0回答:1

我有以下使用 select 的代码:

fd_set fdsu;
FD_ZERO(&fdsu);
FD_SET(fd, &fdsu);
fd_set efds = fdsu;
fd_set dfds = fdsu;
while (1) {
    select(cameraUSBP.fd + 1, NULL, &dfds, &efds, NULL);
    if (FD_ISSET(cameraUSBP.fd, &efds)) {
        errorData();
    }
    if (FD_ISSET(cameraUSBP.fd, &dfds)) {
        writeData();
    }
}

我想将其移植以使用 poll:

struct pollfd pollfds[1];
pollfds[0].fd = fd;
pollfds[0].events = POLLIN;
while (1) {
    poll(pollfds, 1, -1);
    //how to insert writeData() and errorData()
}

我很困惑。如何插入 writeData 和 errorData 事件?

c linux posix-select poll-syscall
1个回答
2
投票

首先,您的

select()
版本有许多重大错误。

来自 linux 手册页

请注意:返回后,每个文件描述符集都会被修改以指示哪些文件描述符当前“就绪”。因此,如果在循环中使用

select()
,则在每次调用之前必须重新初始化集合。

你没有这样做。您也无法像您正在做的那样可移植地分配

fd_set

;它适用于某些实现,但不适用于其他实现(例如,如果它是作为数组实现的)。您也不会检查 
select()
 是否失败。

它应该看起来像

while (1) { fd_set efds, dfds; FD_ZERO(&efds); FD_SET(cameraUSBP.fd, &efds); FD_ZERO(&dfds); FD_SET(cameraUSBP.fd, &dfds); if (select(cameraUSBP.fd + 1, NULL, &dfds, &efds, NULL) < 0) { reportError(errno); break; // or exit or whatever } if (FD_ISSET(cameraUSBP.fd, &efds)) { errorData(); } if (FD_ISSET(cameraUSBP.fd, &dfds)) { writeData(); } }
另一方面,

struct pollfd

 对于要监视的事件和发生的事件有单独的字段,因此如果您正在监视的描述符从不更改,则只需初始化一次。您使用按位或标志将 
events
 设置为您感兴趣的内容,然后检查 
revents
 以查看通过按位和相关标志执行操作时发生了什么。

struct pollfd pollfds[1]; pollfds[0].fd = cameraUSBP.fd; pollfds[0].events = POLLOUT; // since you want to know when it's writable while (1) { if (poll(pollfds, 1, -1) < 0) { reportError(errno); break; } if (pollfds[0].revents & POLLERR) { // Doesn't need to be set in events errorData(); } if (pollfds[0].revents & POLLOUT) { writeData(); } }
    
© www.soinside.com 2019 - 2024. All rights reserved.