How to call the interrupted system in Linux

How to call the interrupted system in Linux

Preface

Slow system calls refer to system calls that may never return, thus blocking the process forever. For example, accept when there is no client connection and read when there is no input are both slow system calls.

In Linux, when a process blocked in a slow system call captures a signal, the system call will be interrupted and the signal processing function will be executed instead. This is the interrupted system call.

However, when the signal processing function returns, the following situations may occur:

  • If the signal processing function is registered with signal, the system call will be automatically restarted and the function will not return.
  • If the signal processing function is registered with sigaction
    • By default, the system call will not be automatically restarted, the function will return failure, and errno will be set to EINTR
    • The system call will automatically restart only when the SA_RESTART flag of the interrupt signal is valid.

Next, we write code to verify the above situations respectively, where the system call selects read, the interrupt signal selects SIGALRM, and the interrupt signal is generated by alarm.

Using signal

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>

void handler(int s)
{
  printf("read is interrupted by signal handler\n");
  return;
}

int main()
{
  char buf[10];
  int nread = 0;

  signal(SIGALRM, handler);
  alarm(2);

  printf("read start\n");
  nread = read(STDIN_FILENO, buf, sizeof(buf));
  printf("read return\n");

  if ((nread < 0) && (errno == EINTR))
  {
    printf("read return failed, errno is EINTR\n");
  }

  return 0;
} 

Use sigaction + default

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>

void handler(int s)
{
  printf("read is interrupted by signal handler\n");
  return;
}

int main()
{
  char buf[10];
  int nread = 0;
  struct sigaction act;

  sigemptyset(&act.sa_mask);
  act.sa_handler = handler;
  act.sa_flags = 0; //Do not set the SA_RESTART flag for the SIGALRM signal, and use the default processing method of sigaction //act.sa_flag |= SA_INTERRUPT; //SA_INTERRUPT is the default processing method of sigaction, that is, it does not automatically restart the interrupted system call. //In fact, no matter what the value of act.sa_flags is, as long as SA_RESTART is not set, sigaction is processed according to SA_INTERRUPT sigaction(SIGALRM, &act, NULL);
  alarm(2);

  printf("read start\n");
  nread = read(STDIN_FILENO, buf, sizeof(buf));
  printf("read return\n");

  if ((nread < 0) && (errno == EINTR))
  {
    printf("read return failed, errno is EINTR\n");
  }

  return 0;
} 


Use sigaction + specify the SA_RESTART flag

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>

void handler(int s)
{
  printf("read is interrupted by signal handler\n");
  return;
}

int main()
{
  char buf[10];
  int nread = 0;
  struct sigaction act;

  sigemptyset(&act.sa_mask);
  act.sa_handler = handler;
  act.sa_flags = 0;
  act.sa_flags |= SA_RESTART; //Set the SA_RESTART flag for the SIGALRM signal sigaction(SIGALRM, &act, NULL);
  alarm(2);

  printf("read start\n");
  nread = read(STDIN_FILENO, buf, sizeof(buf));
  printf("read return\n");

  if ((nread < 0) && (errno == EINTR))
  {
    printf("read return failed, errno is EINTR\n");
  }

  return 0;
} 


Due to the differences in how interrupted system calls are handled, the issues related to interrupted system calls for applications are:

  • The application cannot always know how the signal handler was registered and whether the SA_RESTART flag is set.
  • Portable code must explicitly handle error returns from key functions. When a function fails and errno equals EINTR, you can handle it accordingly, such as restarting the function.
int nread = read(fd, buf, 1024);

if (nread < 0)
{
  if (errno == EINTR)
  {
    //The read is interrupted, which should not be considered a failure. You can handle it according to actual needs, such as rewriting the call to read, or ignoring it.}
  else
  {
    //read the real read error}
}

Summarize

The above is the full content of this article. I hope that the content of this article will have certain reference learning value for your study or work. Thank you for your support of 123WORDPRESS.COM.

You may also be interested in:
  • Get the system call and parameters of a process in Linux (troubleshooting case)
  • Detailed analysis of the difference between library functions and system calls in Linux C
  • Detailed analysis of the difference between Linux system calls and standard library calls
  • Three ways to implement Linux system calls
  • Method based on Linux system call--getrlimit() and setrlimit() functions
  • Detailed explanation of the Linux system call principle
  • Linux kernel device driver system call notes

<<:  MySQL configuration SSL master-slave replication

>>:  React antd realizes dynamic increase and decrease of form

Recommend

Web Design Tutorial (7): Improving Web Design Efficiency

<br />Previous article: Web Design Tutorial ...

The hottest trends in web design UI in 2013 The most popular UI designs

Time flies, and in just six days, 2013 will becom...

Metadata Extraction Example Analysis of MySQL and Oracle

Table of contents Preface What is metadata Refere...

About uniApp editor WeChat sliding problem

The uniapp applet will have a similar drop-down p...

Windows Server 2019 Install (Graphical Tutorial)

Windows Server 2019 is the latest server operatin...

How to represent various MOUSE shapes

<a href="http://" style="cursor...

A very detailed explanation of the Linux DHCP service

Table of contents 1. DHCP Service (Dynamic Host C...

CSS injection knowledge summary

Modern browsers no longer allow JavaScript to be ...

MySql multi-condition query statement with OR keyword

The previous article introduced the MySql multi-c...

Building an image server with FastDFS under Linux

Table of contents Server Planning 1. Install syst...

Vue+Element realizes paging effect

This article example shares the specific code of ...

How to use the MySQL authorization command grant

The examples in this article run on MySQL 5.0 and...

MySQL 8.0 Window Function Introduction and Summary

Preface Before MySQL 8.0, it was quite painful to...