gpt4 book ai didi

c - 为什么拔掉 USB 线后 select 返回?

转载 作者:行者123 更新时间:2023-12-04 09:37:14 25 4
gpt4 key购买 nike

我遇到一些使用 select、FD_ISSET、read 等从 ttyUSB 端口读取的 linux c 代码的问题。我的调制解调器使用 FTDI 串行到 USB 电缆进行输入。问题是当 USB 电缆被拔出时选择解锁。有没有办法阻止它这样做?

count = 0;
while ( g_running ) {
FD_ZERO(&readFdSet);
maxfd = 0;
numTransPorts = 0;
logger( DEBUG, "Begin g_running loop - %d", count );
for ( i = 0; i < MAX_CONFIG_PORTS; i++ ) {
if ( configPorts[i].commType == 1 && configPorts[i].pttyHost != NULL ) {
FD_SET( configPorts[i].pttyHost->fd, &readFdSet );
logger( DEBUG, "FD_SET - fd=%d, index=%d", configPorts[i].pttyHost->fd, i );
if ( configPorts[i].pttyHost->fd >= maxfd ) {
maxfd = configPorts[i].pttyHost->fd;
}
numTransPorts++;
}
}
maxfd++; // add one because select check a range to n-1 file descriptors
if ( maxfd != 0 ) { // indicates no ports are available
logger( DEBUG, "Calling select() with %d ports and maxfd of %d", numTransPorts, maxfd );
logger( INFO, "Waiting for input ..." );
select( maxfd, &readFdSet, NULL, NULL, NULL ); // blocking until one available
if( result == -1 ){
logger( INFO, "select() error. errno: %d", errno );
} else if ( result > 0 ){
for ( i = 0; i < MAX_CONFIG_PORTS; i++ ) {
if ( FD_ISSET( configPorts[i].pttyHost->fd, &readFdSet ) ) { // input is available
logger( INFO, "Input on port %s", configPorts[i].pttyHost->serialPath );
result = serialPortRead( buffer, configPorts[i].pttyHost->fd );
if ( result <= 0 ) {
// there was an error due to the file descriptor. It
// probably indicates that the tty ports are no longer available
}
}
}
} else {
logger ( INFO, "select() returns 0" );
}
}
count++;
}

串口读取:

int serialPortRead( char *buf, int serialHandle ) {
//char ch;
char *ptr;
int res = 0;
int bytesRead = 0;
int i;

logger( TRACE, "TRACE: serialPortRead() with fd = %d", serialHandle );

ptr = buf;

// try 3 times
for ( i = 0; i < 3; i++ ) {
while ( (res = read( serialHandle, ptr, 1 )) > 0 ) { // read 1 byte at a time
if ( *ptr == 0x0d ) { //there is 0x0d as a terminate byte from ECR
break;
}
ptr += res;
}
if ( res < 0 && errno == EAGAIN ) {
continue;
} else {
break;
}
}

*ptr = 0x00; // set 0x00 as a terminate byte
// pthread_mutex_unlock(&g_serial_trans_mutex);
if ( res < 0 ) {
// if res is -1, there is an error
bytesRead = -1;
logger( DEBUG, "serialPortRead error. errno = %d", errno );
} else {
bytesRead = (int) (ptr - buf);
logger( DEBUG, "serialPortRead %d bytes", bytesRead );
}

return bytesRead;
}

当 USB 电缆被拔出时,select() 解锁,暗示输入可用,FD_ISSET 返回真。 serialPortRead 中的 read() 将返回已读取的零字节。然后它循环回到 select() ,它再次解除阻塞,说输入可用,等等。因此,您会得到 select() 的无限循环,FD_ISSET 返回 true,fd 永远不会被清除,read 返回 0 等等。我怎样才能解决这个问题?我期望的行为是当没有什么可读的时候 select 不会错误地解锁?

注意:当 select 解锁时它返回一个正数

最佳答案

select() 正在返回,因为有信息要读取 - 在本例中,文件描述符已到达“文件末尾”这一事实。这由返回 0read() 指示。

read() 返回 0 时,您应该关闭相应的文件描述符。

关于c - 为什么拔掉 USB 线后 select 返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10899011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com