强制读取系统调用阻塞 [英] Force read system call to block

查看:53
本文介绍了强制读取系统调用阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序可以读取和写入串行端口.我有一个读取器线程,它读取数据并向共享内存提供信息.读取器线程应该休眠直到数据可用.所以我想进行 read() 系统调用来阻止调用线程.考虑到手册页,除非你将 O_NONBLOCK 提供给 openread 应该总是阻塞的.但是我有一个活动线程,其中 read 不断返回 -1 .也改变 VTIMEVMIN 没有什么区别.这是打开端口的方式:

I have a program that reads from and writes to serial port. I have a reader thread that reads data and supplies informations to shared memory. The reader thread should sleep until data is available. So I want to make read() system call to block calling thread. Considering man pages, unless you supply O_NONBLOCK to open, read should always block. But I have an active thread which in it read returns -1 continuously. ALso changing VTIME and VMIN does not make a difference. This is how port is opened:

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
    }
 }

推荐答案

此处需要考虑的一些事项.

A few things to consider here.

首先,read 可以返回的原因有很多.任何类型的中断都会导致读取解除阻塞并返回 -1,文件也可能存在问题.检查 errno 变量以获取有关它为什么返回 -1 的更多信息.可能的 errno 值的描述在 阅读手册页

First, read can return for a number of reasons. Interrupts of any kind will cause read to unblock and return -1, also there could be an issue with the file. Check errno variable for more information on why it is returning -1. Description of possible errno values are in the read man page

第二,在您解决上述问题后,当数据可用时,不能保证在一次读取中为您提供整个网络数据包,因此您可能需要从多次读取中重新组装.

Second, after you've solved the above, when data is available read is not guaranteed to give you an entire network packet in a single read, so you might need to reassemble from multiple reads.

这篇关于强制读取系统调用阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆