Main Content

Signal call in multithreaded program

Program with multiple threads uses signal function

Description

This checker is deactivated in a default Polyspace® as You Code analysis. See Checkers Deactivated in Polyspace as You Code Analysis (Polyspace Access).

This defect occurs when you use the signal() function in a program with multiple threads.

Risk

According to the C11 standard (Section 7.14.1.1), use of the signal() function in a multithreaded program is undefined behavior.

Fix

Depending on your intent, use other ways to perform an asynchronous action on a specific thread.

Examples

expand all


#include <signal.h>
#include <stddef.h>
#include <threads.h>

volatile sig_atomic_t flag = 0;

void handler(int signum) {
  flag = 1;
}

/* Runs until user sends SIGUSR1 */
int func(void *data) {
  while (!flag) {
    /* ... */
  }
  return 0;
}

int main(void) {
  signal(SIGINT, handler); /* Undefined behavior */
  thrd_t tid;

  if (thrd_success != thrd_create(&tid, func, NULL)) {
    /* Handle error */
  }
  /* ... */
  return 0;
}

In this example, the signal function is used to terminate a while loop in the thread created with thrd_create.

Correction — Use atomic_bool Variable to Terminate Loop

One possible correction is to use an atomic_bool variable that multiple threads can access. In the corrected example, the child thread evaluates this variable before every loop iteration. After completing the program, you can modify this variable so that the child thread exits the loop.


#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <threads.h>
  
atomic_bool flag = ATOMIC_VAR_INIT(false);
 
int func(void *data) {
  while (!flag) {
    /* ... */
  }
  return 0;
}
 
int main(void) {
  thrd_t tid;
   
  if (thrd_success != thrd_create(&tid, func, NULL)) {
    /* Handle error */
  }
  /* ... */
  /* Set flag when done */
  flag = true;
 
  return 0;
}

Result Information

Group: Concurrency
Language: C | C++
Default: Off
Command-Line Syntax: SIGNAL_USE_IN_MULTITHREADED_PROGRAM
Impact: Low

Version History

Introduced in R2018b