【问题标题】:errno 11 [EAGAIN] from read(2)errno 11 [EAGAIN] 来自读取(2)
【发布时间】:2013-10-09 09:49:21
【问题描述】:

我有一些代码可以读取我的 pinguin 盒子上的串行端口。 代码如下:

while ( 1 )  
if ( select( handle + 1, &h, NULL, NULL, &tm ) > 0 )  
{  
    if( read( handle, &msg, 1 ) > 0 )  
    {  
        ... tips and trixes  
    }  
    if ( gotWhatINeed ) break;  

代码可以运行很长时间,但如果我尝试稍微强调一下,我会开始不断地得到 errno 11 (EAGAIN),即使在压力完成之后也是如此。 现在我想知道我误解了什么,从 man 2 select 我可以理解 select 返回句柄中可用的字节数。

也许有趣的是代码总是在分离的线程中运行。

基于cmets,我现在贴出更多代码细节。

主要是我有

pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

int main ( int argc, char **argv )
{
    pthread_t scan_01
    signal( 11, OnSignal );
    pthread_mutex_init( &mut, NULL );
    .....
    pthread_create(&scan_01, NULL, (void *)readDevice, NULL);
    pthread_detach(scan_01);

以及读取设备的方法。 TGM 是一个保存读取数据的结构。 OnSignal 只是记录信号。 _note: 问题

void *readDevice(void)
{
    int r;
    char  b[256];
    struct TGM tgm;
    pthread_t new, self;
    pthread_mutex_lock( &mut );
    self = pthread_self( );
    while( 1 )
    {
        FD_ZERO( &out );
        FD_SET( fOut, &out );
        tm.tv_sec = LOOP_DELAY;
        tm.tv_usec = com_scan_time;

        if ( select( fOut + 1, & out, NULL, NULL, &tm ) > 0 )
        {
            r = readPort( fOut, 10, b, 1 );
            pthread_mutex_unlock( &mut );
            pthread_create( &new, NULL, (void *)readDevice, NULL );
            pthread_detach( new );
            iThreads++;
            ...
            break;

        }    
    }
    self = pthread_self();
    iThreads--;
    pthread_exit( & self );

readPort 就像,主要任务是“只是”将位和字节转换为 TGM。

int readPort(const int handle, char terminator, char b[256], int crc)
{
    char    msg;
    fd_set  h;
    struct  timeval tm;

    do
    {
        FD_ZERO( &h );
        FD_SET( handle, &h );
        tm.tv_sec  = LOOP_DELAY;
        tm.tv_usec = com_scan_time;

        if ( select( handle + 1, &h, NULL, NULL, &tm ) > 0 )
        {
            if( read( handle, &msg, 1 ) > 0 )
            {

                if( msg == 3 ) // marks end of message
                ....
            }
            else
            {
                log( ERRLOG, "FAILED to read port (%d) %s\n", 
                    errno, 
                    strerror( errno ) );
                return -1;
            }

现在我的失败在哪里 :D 在大约 30 条消息之后,我在注入时得到的输出(意味着在大约 30 个线程之后 - 有时会多一点,有时会少一点) 未能读取端口 (11) 资源暂时不可用 _信号 11_

感谢您在我身上花费了一些时间,我非常感激。

【问题讨论】:

  • select() 返回可用文件描述符的数量; read() 返回消耗的字节数数。
  • 另外,为什么一次只读取一个字节?请注意,EAGAIN 通常表示您已尝试从非阻塞套接字读取,因此那里有其他问题。
  • 您的意思是 errno code EAGAIN,而不是 signal 11 (SIGSEGV),对吗?这是两个完全不相关的事情,并且会表明完全不同的问题。 (除此之外:从不通过它们的数值引用 errno 代码,只有它们的 strerror 文本或它们的 errno.h 名称。这些数字在平台之间甚至在具有相同内核的 CPU 之间不一致(不像较小的信号号))。
  • 扎克:我猜两者都有。读取返回 11 并且根据 man 2 读取,这是再次。但在这种情况下也会发出信号 11。
  • Chrisaycock:如果两个线程同时读取同一个端口?

标签: c serial-port signals posix


【解决方案1】:

你是否有 30 个线程都在 select() 上被阻塞,当它变得可读时都竞相读取 fOut --- 然后当缓冲区耗尽时失败者给你 EAGAIN?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-28
    相关资源
    最近更新 更多