Alarm function usage and read function usage discussion

Source: Internet
Author: User
Tags sigalarm sprintf strlen

This is a piece of code that the client receives a service-side answer in a short socket connection:

/************ Receive Response message ****************/
Alarm (20);
Iret=read (yktsocketid,recvbuf,2048);
Alarm (0);
if (iret<=0)
{
memset (logbuf,0,sizeof (LOGBUF));
sprintf (Logbuf, "iret=[%d],file=[%s],line=[%d]\n", iret,__file__,__line__);
Lwritelog (Logfile,logbuf,strlen (LOGBUF), 6);
return-1;
}

The main idea of the code is to set a 20-second time-out. If the server answers time-outs, captures the sigalarm signal, IRET<=0 returns an error message.

So now the problem is, the default processing of the Sigalarm signal is to terminate the process: This is different from what we expected, and was meant to be sigalarm after capturing the signal in the read call and returning an error. Then the processing of the sigalarm signal needs to be rewritten to allow the process to be terminated.

struct Sigaction Act;
Act.sa_handler = Alarm_catch;
Sigemptyset (&act.sa_mask);
Act.sa_flags |= Sa_interrupt;

Sigaction (SIGALRM, &act,null);

Alarm (20);
Iret=read (yktsocketid,recvbuf,2048);
Alarm (0);
if (iret<=0)
{
memset (logbuf,0,sizeof (LOGBUF));
sprintf (Logbuf, "iret=[%d],file=[%s],line=[%d]\n", iret,__file__,__line__);
Lwritelog (Logfile,logbuf,strlen (LOGBUF), 6);
return-1;

}

This rewrite of the sigalarm signal processing can be a perfect solution to the problem of the termination process, then the code is perfect now. It's not that simple, hehe.

There is a race condition between the first a l a r m call and the R e a D call. If the kernel is in between these two function calls so that the process cannot occupy the processor and its time is longer than the alarm
, then r e a D may block forever. Timeout will expire ....

This problem can be introduced setjmp to solve

    struct Sigaction Act;
    static jmp_buf ENV_ARLM;
    Act.sa_handler = Alarm_catch;
    Sigemptyset (&act.sa_mask);
    Act.sa_flags |= sa_interrupt;
    sigaction (SIGALRM, &act,null);
    
        if (setjmp (ENV_ARLM) ==0)
       {               alarm (20);
             iret=read (yktsocketid,recvbuf,2048);
    Alarm (0);
    if (iret<=0)
    {
  memset (logbuf,0,sizeof (LOGBUF));
    sprintf (logbuf, "iret=[%d],file=[%s],line=[%d]\n", iret,__file__,__line__);
    Lwritelog (Logfile,logbuf,strlen (LOGBUF), 6);
  return-1;
  &NBSP;}
}
Return (alarm (0));

static void Alarm_catch ()
{
   longjmp (ENV_ARLM, 1);
}

This allows the system to jump directly to return even if the timeout process is completed before read. Does not jump to read slow IO this piece

In addition a small problem is added:

In my program, I defined a

Long BankID;

There is no initialization, the bankid=5555 is called, and garbled characters are still present after the value is assigned. The automatic variable is still initialized, today

It's an education.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.