First, thread safety

1. Basic concepts of thread safety

When multiple threads access a method or variable, no matter how the method is called or how the threads are run interchangeably, each thread’s execution results in the correct behavior we expect, and the method or variable is thread-safe.

2. Thread insecurity scenario

Multithreaded access to global variables, due to the CPU scheduling order is different, threads run alternately, may read the same value at one time, and then write count to each other, data pollution, resulting in the final result does not meet expectations (20000)

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>

int count = 0;

void *task()
{
    int i = 0;
    for (; i < 10000; i++) {
        count++;
        printf("count1:%d\n", count); }}int main()
{
    pthread_t a;
    pthread_t b;

    pthread_create(&a, NULL, task, NULL);
    pthread_create(&b, NULL, task, NULL);

    pthread_join(a, NULL);
    pthread_join(b, NULL);
    return 0;
}

Copy the code

3. Common methods to implement thread safety

  • (1) Atomic operation (single instruction operation)
  • (2) Synchronization and locking, to ensure that the two threads in the critical area of the public resources at the serial execution
  • (3) Make the task function itself a thread-safe function (such as not using global variables, static variables)

Second, signal security

1. Signal security concept

The general signal security refers to that in signal processing, when abnormal signal occurs, the call of signal processing function will not cause other function changes except signal processing function. Reentrant functions are signal-safe, so usually non-reentrant functions are not signal-safe, just as malloc/free is a signal-unsafe function that maintains a global shared memory linked list and is locked.

2. The signal is not secure

If at this time a thread is calling malloc/free, and just after the malloc function locks, it is interrupted by an abnormal signal and enters the signal processing function. If the malloc/free and other signal non-safe functions are called in the signal processing function, then the heap lock for the same thread is continuously added twice. Deadlock occurs (deadlock reason: thread A has been waiting for the main program to unlock in the signal processing function, resulting in blocking, and can not return to the normal program in the signal processing function, different from the common understanding that two threads generate deadlock), resulting in exceptions. To construct a situation where malloc is called again after malloc has been locked, a thread loop needs to be opened to send an exception signal to another thread that has called Malloc. This thread receives the exception signal and enters the signal handler, which can reproduce the deadlock scenario.

When malloc is called again after malloc is locked, the program freezes

3. How to achieve signal security

(1) Do not use the signal unsafe function in the signal processing function, because although this situation belongs to a small probability event, but it will lead to abnormal program, or even directly restart reset, and it is difficult to locate
(2) determine whether function signal safety function view | MT – Safe | the AS – Safe | AC – Safe | these three features

www.gnu.org/software/li…

www.gnu.org/software/li…

Reentrant functions

1. Reentrant concept

A function is reentrant, indicating that the function has not completed execution, but has been re-entered due to external or internal factors. A function is called reentrant, indicating that the function is reentrant without any adverse consequences.

2. Reentrant most common scenarios

Reentrant function refers to the function in the process of execution is interrupted, the execution of the program flow to run to another place to put the function to perform again, again where the return of the execution is completed to interrupt function before operation, and the whole process will not affect the end result of the interruption function, the following figure:

3. Non-reentrant features

  • 1) Static data structures (global or static variables) are used or returned,
  • 2) Part of the standard I/O library (there will be a global lock inside, lock is also a state)
  • 3) a non-reentrant function is called, such as malloc or free (malloc maintains a global linked list internally to manage allocated memory, which is state information, as is free), and malloc is itself thread-safe, However, there is a global heap lock in the system call, and the malloc function in the signal handle may occur when the main program calls malloc, but before the end, the heap lock is not released, and is interrupted by the signal. When the malloc function is called again, the same thread locks the heap lock twice in a row, creating a deadlock deadlock.

Four, thread safety, signal safety, reentrant function three differences and connection

1. A function can be thread-safe but not reentrant. For example, a function that protects some shared resource through mutex is thread-safe from a thread-safe perspective, but is not reentrant because mutex is used to make the function ststate.

2. But reentrant functions are certainly thread-safe and signal-safe

3. Thread-safe is not necessarily signal-safe