Linux---thread safety

Thread safe

Multiple execution streams compete for access to critical resources without causing data ambiguity or logical confusion. The process of competing for access between threads is thread-safe.

Implementation of thread safety

  • Synchronization: Realize timing rationality of access to critical resources through conditional judgment.
  • Mutual exclusion: Through unique access, the security of access to critical resources is realized.
    Synchronization and mutual exclusion can also achieve security between processes. Semaphores can not only achieve synchronization, but also achieve synchronization.

Implementation of synchronization

Condition variable realizes
condition variable: the idea of ​​realizing synchronization provides users with two interfaces (one is responsible for letting the thread fall into a blocked sleep interface, the other is responsible for waking up the thread) + pcb waiting queue

substance

Through conditional judgment, when can the thread be allowed to access the critical resource, if it cannot be accessed, the thread will be blocked; if it can be accessed, the thread will be awakened to realize the rationality of the thread's access to the critical resource.

Consumers and producers:
Insert picture description here
Note: The condition variable only provides an interface for waiting and waking up. It does not have the function of condition judgment, which means: the condition variable judgment needs to be completed by the user.
Interface function of condition variable

  • Define the condition variable pthread_cond_t cond
  • Initialize the condition variable
pthread_cond_init(pthread_cond_t *cond,pthread_cond_condattr_t *attr)
cond = PTHREAD_COND_INITALIZER
  • The interface that makes a thread wait:, pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex)the interface has three sub-operations, a: unlock b: suspend waiting c: lock
	pthread_cond_timewait(pthread_cont_t *cond,pthread_mutex_t *mutex,struct timespec *abstime);
	
	限制等待时长的阻塞条件:等待一段指定的时间,时间到了调用就报错返回-ETIMEOUT

The thread waiting interface adds threads that cannot access critical resources into the waiting queue. Condition variables are used in conjunction with mutex locks. Condition variables do not provide the function of condition judgment, and need to be judged by the user (usually the judgment of the condition is the access of a critical resource), so the access to this resource needs to be protected, so it is necessary Used in conjunction with a mutex lock.

  • An interface to
    pthread_cond_signal(pthread_cond *cond);wake up at least one thread to
    pthread_cond_broadcast(pthread_cond *cond)wake up all waiting threads
  • If the conditions are not used, the resources will be destroyed:pthread_destroy(pthread_cond *cond)

The realization principle of mutual exclusion

Only one execution flow can access critical resources at a time.

  • Mark critical resources: when no one visits, mark it as 1, indicating that it can be accessed; when someone visits, mark it as 0, which indicates that it cannot be accessed.
  • When accessing a critical resource, first determine whether it can be accessed, and if it cannot be accessed, the thread sleeps.

Technology of mutual exclusion realization: mutual exclusion lock

A mutex
is essentially a counter. As long as a counter of 0/1 is used to mark the current access status of the resource, 1 means accessible, and 0 means inaccessible.

Locking
Each thread must access the mutex lock before accessing critical resources.

Mutex lock principle
Insert picture description here

  • 1: Modify the value on the cpu register to 0, and then exchange data with the counter in the memory (meaning that the counter becomes 0 at this time, and whoever accesses it is an inaccessible state)
  • 2: If the register exchange data is 0, it means that it is currently inaccessible, and the pcb state is set to a blocked state, and the thread will be suspended and waited.
  • 3: If the value of the register exchange is 1, it means that it is currently accessible, and the lock operation returns directly, which means that the lock is successful and continues to access the resource.
  • 4: After accessing the data, unlock it (change the value of the counter in the memory back).

Mutex locks are locked before accessing resources and unlocked after the access ends, thereby achieving atomicity of mutex counting.

The mutex itself is a critical resource

Mutex lock operation process

  • Define the mutex variable pthread_mutex_t mutex;
  • Initialize the mutex
mutex = PTHREAD_MUTEX_INITALIZER
int pthread_mutex_init(pthread_mutex *mutex,pthread_mutexattr_t *attr)
mutex:互斥锁变量首地址
attr:互斥锁属性,通常为NULL
  • Before accessing critical resources, lock first
int pthread_mutex_lock(pthread_mutex_t *mutex);阻塞加锁,如果不能加锁,则一直等待
int pthread_mutex_trylock(pthread_mutex_t *mutex);非阻塞加锁,如果不能加锁,则报错返回
  • After the access to the critical resource is completed, unlock the operation (mark the state as accessible)
int pthread_mutex_unlock(pthread_mutex_t *mutex);
  • Do not use locks, eventually release resources and destroy mutex locks
int pthread_mutex_destroy(pthread_mutex_t mutex);

The initialization of the lock must be before the thread is created.
After locking, unlock it at any place where it is possible to exit
The destruction of the lock must be when no one uses the mutex lock

Deadlock

Cause
Multiple execution flow pairsLock resourceScrambled for access, but due to improper advancement sequence, they waited for each other, and finally caused the program flow to fail to complete.

Necessary conditions for deadlock

  • Mutually exclusive conditions: A lock cannot be added to multiple execution streams at the same time, and if one execution stream has a lock, others cannot add the lock. At the same time, only one thread can lock.
  • Inalienable resources: a thread has to unlock it by itself if it is locked, and other threads do not have the power to unlock it.
  • Request and hold conditions: take this lock and grab another lock
  • Loop waiting condition: thread 1 grabs lock A, then grabs lock B, thread 2 grabs lock B, and then grabs lock A

How to avoid deadlock

  • Banker's algorithm
  • Deadlock judgment algorithm

Guess you like

Origin blog.csdn.net/qq_42708024/article/details/104443647