[英]let the system call `select()` block until a socket gets something to read
[英]Force read system call to block
我有一個程序可以讀取和寫入串行端口。 我有一個讀取器線程,它讀取數據並向共享內存提供信息。 讀者線程應該睡眠,直到數據可用。 所以我想讓read()
系統調用來阻塞調用線程。 考慮手冊頁,除非您提供O_NONBLOCK
open
,否則應始終禁止read
。 但我有一個活動的線程,其中read
連續返回-1
。 同時改變VTIME
和VMIN
並沒有什么不同。 這是端口的打開方式:
fd = open(portName.str().c_str()/*/dev/ttyS2*/, O_RDWR | O_NOCTTY);
if (fd < 0) // if open is not successful
{
cerr << ERROR << "Unable to open `" << portName << "'." << endl;
return false;
}
else
{
cout << INFO << "Port " << portName.str() << " successfully opened."
<< endl;
cout << INFO << "Configuring port..." << endl;
fcntl(fd, F_SETFL,0);
struct termios port_settings; // structure to store the port settings in
cfsetispeed(&port_settings, B38400); // set baud rate
cfsetospeed(&port_settings, B38400); // set baud rate
port_settings.c_cflag |= CLOCAL | CREAD;
port_settings.c_cflag &= ~CRTSCTS; // disable H/W flow control
port_settings.c_lflag &= ~( ISIG | // disable SIGxxxx signals
IEXTEN | // disable extended functions
ECHO | ECHOE); // disable all auto-echo functions
port_settings.c_lflag &= ~ICANON ; // raw mode
port_settings.c_oflag &= ~OPOST; // raw output
port_settings.c_iflag &= ~(IXON | IXOFF | IXANY); // disable S/W flow control;
// Following values do not change timout in runtime:
port_settings.c_cc[VTIME] = 2; // wait 0.2 second to get data -
port_settings.c_cc[VMIN] = 0;
port_settings.c_cflag = (port_settings.c_cflag &= ~CSIZE) | CS8; // set data byte size
port_settings.c_cflag &= ~CSTOPB; // set stop bit 1
port_settings.c_cflag &= ~PARENB; // set no parity
port_settings.c_iflag |= IGNPAR; // ignore parity
port_settings.c_iflag &= ~(INPCK | ISTRIP | PARMRK);
// Set
if (tcsetattr(fd, TCSANOW, &port_settings) < 0)
{
cerr << ERROR << "Unable to configure serial port." << endl;
return false;
}
else
{
cout << INFO << "Port `" << portName.str()
<< "' configuration was successful." << endl;
}
在讀者線程中:
byte buffer[256];
while (true)
{
int packetSize = read(fd, buffer, 256);
if (packetSize > 0)
{
// use data - this code is never run
}
else
{
// print error - we're always here. no matter how long timout is
}
}
這里要考慮幾件事。
首先,由於多種原因,讀取可以返回。 任何類型的中斷都會導致讀取解除阻塞並返回-1,文件也可能存在問題。 檢查errno變量以獲取有關返回-1的更多信息。 可能的errno值的描述在閱讀手冊頁中
其次,在您解決了上述問題之后,當數據可用時,不能保證讀取只能在一次讀取中為您提供整個網絡數據包,因此您可能需要從多次讀取中重新組合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.