ошибка 11 [EAGAIN] при чтении (2)

#c #serial-port #signals #posix

#c #последовательный порт #сигналы #posix

Вопрос:

У меня есть некоторый код, который считывает последовательный порт в моем pinguin-блоке. Код похож:

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

Код выполняется довольно долго, но если я попытаюсь немного подчеркнуть это, я начинаю постоянно получать ошибку 11 (EAGAIN), даже после завершения подчеркивания.
И теперь мне интересно, что я неправильно понимаю, из man 2 select я могу понять, что select возвращает количество байтов, доступных из дескриптора.

Возможно, представляет интерес то, что код всегда выполняется в отдельном потоке.

Основываясь на комментариях, я сейчас публикую более подробную информацию о коде.

В основном у меня есть

 pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

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

И метод, с помощью которого считывается устройство. TGM — это структура для хранения считанных данных. OnSignal просто регистрирует сигнал. _ примечание: вопрос

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

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

        }    
    }
    self = pthread_self();
    iThreads--;
    pthread_exit( amp; 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( amp;h );
        FD_SET( handle, amp;h );
        tm.tv_sec  = LOOP_DELAY;
        tm.tv_usec = com_scan_time;

        if ( select( handle   1, amp;h, NULL, NULL, amp;tm ) > 0 )
        {
            if( read( handle, amp;msg, 1 ) > 0 )
            {

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

Итак, в чем моя ошибка: D
Результат, который я получаю при вводе, примерно через 30 сообщений (значит, примерно через. 30 потоков — иногда немного больше, а иногда немного меньше — это)
НЕ УДАЛОСЬ прочитать порт (11), Ресурс временно недоступен
_Signal 11_

Спасибо, что уделили мне немного времени, я очень благодарен.

Комментарии:

1. select() возвращает количество доступных файловых дескрипторов ; read() возвращает количество использованных байт .

2. Кроме того, почему вы читаете только один байт за раз? Обратите внимание, что EAGAIN обычно это указывает на то, что вы пытались выполнить чтение из неблокирующего сокета, значит, там что-то еще напортачено.

3.Вы имеете в виду код без ошибок EAGAIN , а не сигнал 11 ( SIGSEGV ), верно? Это две совершенно не связанные вещи, которые указывают на совершенно разные проблемы. (В сторону: никогда не ссылайтесь на коды errno по их числовому значению, только по их strerror тексту или errno.h названию. Числа не согласованы между платформами или даже между процессорами с одним и тем же ядром (в отличие от меньших номеров сигналов)).

4. Зак: Я думаю, и то, и другое. чтение возвращает 11, и, согласно man 2, это повторяется. но в этом случае также возникает сигнал 11.

5. Крисайкок: как в случае, если два потока одновременно читают один и тот же порт?

Ответ №1:

У вас есть 30 потоков, заблокированных в select (), которые все пытаются прочитать fOut, когда он становится доступным для чтения — затем проигравшие дают вам EAGAIN, когда буфер опорожняется?