错误号 11 [EAGAIN] 来自读取 (2)

发布于 2024-10-31 23:36:28 字数 2552 浏览 0 评论 0原文

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

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 返回句柄中可用的字节数。

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

根据评论,我现在发布代码的更多详细信息。

主要是我有

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:ques

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) 资源暂时不可用 _Signal 11_

感谢您抽出宝贵的时间在我身上,我非常感激。

I have some code that reads the serial port on my pinguin box.
Code is like:

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

Code runs for pretty long time okay, but if I try to stress it a little I start to get errno 11 (EAGAIN) constantly, even after the stress completed.
And now I am wondering what I misunderstand, from man 2 select I can understand select returns the number of bytes availible from the handle.

Maybe it is of interest that the code always runs in a detached thread.

Based on the comments, I now post more details of the code.

In main I have

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);

And the method where the device is read. TGM is a structure to hold the data read. OnSignal is just logging the signal. _note: ques

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 is like, main task is "just" to translate bits and bytes to a 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;
            }

Now where is my failure :D
The output I get when injecting, after some 30 messages ( means after aprox. 30 threads - sometimes a little more, and sometimes a little less is )
FAILED to read port (11) Resource temporarily unavailable
_Signal 11_

Thank you for using some time on me, I am very grateful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伊面 2024-11-07 23:36:28

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

Do you have 30 threads all blocked on select() that all race to read fOut when it becomes readable---then the losers give you EAGAIN when the buffer is drained?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文