在循环和多个操作中使用 select 系统调用
Using select system call in a loop and multiple operations
我正在尝试向串行端口文件写入和读取数据/dev/ttyUSB0,如果操作在 5 秒内不成功,我将继续。为了实现这一点,我选择使用 select() 系统调用。但是,我使用它的确切情况似乎无法按预期工作。以下代码:
简单地说,我需要检查 8 台设备 的状态。所以我必须先write()一个查询命令。然后等待设备的响应 timeout 秒。
应该对 UART 上连接的所有 8 个设备执行此过程。
我不确定是否必须重新初始化 fdset 才能使用 select。
结果:第一次 select 等待 5 秒超时。但之后它立即显示 "timeout" 没有等待。
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 10;
for(i=0; i <= noOfDevicesDiscovered; i++)
{
if( i < 9 && i > 0)
{
uart_init();
printf("ID: %d\n", i);
address = ((i-1)<<1) | 0x01;
command = 0xA0;
fd_set set;
FD_ZERO(&set);
FD_SET(uart_fd, &set);
write(uart_fd, &address, 1);
write(uart_fd, &command, 1);
rv = select(uart_fd + 1, &set, NULL, NULL, &timeout);
if(rv == -1)
perror("select\n");
else if(rv == 0)
{
printf("timeout\n");
new.level = 0;
new.address = i;
fwrite(&new, sizeof(struct Light_Info), 1, fptr);
continue;
}
else
{
read( uart_fd, &level, 1 );
new.level = level;
}
new.address = i;
fwrite(&new, sizeof(struct Light_Info), 1, fptr);
close(uart_fd);
FD_ZERO(&set);
}
}
我们如何解决这个问题。
您需要在每次调用 select 后重新初始化 "timeout"。来自 select 手册页; "On Linux, select() modifies timeout to reflect the amount of time not slept"。所以在你的情况下,在第一次 select 调用之后,你的超时值都是 0。因此对 select 的后续调用将立即超时。
我正在尝试向串行端口文件写入和读取数据/dev/ttyUSB0,如果操作在 5 秒内不成功,我将继续。为了实现这一点,我选择使用 select() 系统调用。但是,我使用它的确切情况似乎无法按预期工作。以下代码:
简单地说,我需要检查 8 台设备 的状态。所以我必须先write()一个查询命令。然后等待设备的响应 timeout 秒。
应该对 UART 上连接的所有 8 个设备执行此过程。 我不确定是否必须重新初始化 fdset 才能使用 select。
结果:第一次 select 等待 5 秒超时。但之后它立即显示 "timeout" 没有等待。
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 10;
for(i=0; i <= noOfDevicesDiscovered; i++)
{
if( i < 9 && i > 0)
{
uart_init();
printf("ID: %d\n", i);
address = ((i-1)<<1) | 0x01;
command = 0xA0;
fd_set set;
FD_ZERO(&set);
FD_SET(uart_fd, &set);
write(uart_fd, &address, 1);
write(uart_fd, &command, 1);
rv = select(uart_fd + 1, &set, NULL, NULL, &timeout);
if(rv == -1)
perror("select\n");
else if(rv == 0)
{
printf("timeout\n");
new.level = 0;
new.address = i;
fwrite(&new, sizeof(struct Light_Info), 1, fptr);
continue;
}
else
{
read( uart_fd, &level, 1 );
new.level = level;
}
new.address = i;
fwrite(&new, sizeof(struct Light_Info), 1, fptr);
close(uart_fd);
FD_ZERO(&set);
}
}
我们如何解决这个问题。
您需要在每次调用 select 后重新初始化 "timeout"。来自 select 手册页; "On Linux, select() modifies timeout to reflect the amount of time not slept"。所以在你的情况下,在第一次 select 调用之后,你的超时值都是 0。因此对 select 的后续调用将立即超时。