Linux kernel design and implementation notes--Introduction to Kernel synchronization

Source: Internet
Author: User
Tags mutex semaphore

Related Concepts Competition conditions

Multiple threads of execution (process/thread/interrupt handler) concurrently (parallel) access to shared resources because the execution order is different, which results in a different situation, called a race condition (race condition)

Examples Show

#include<thread>usingnamespacestd;int  0;void thread1(){    //for(int x=0;x<100000;x++)     i++;}void thread2(){    //for(int x=0;x<100000;x++)     i++;}int main(){    std::thread t1(thread1);    std::thread t2(thread1);    t1.join();    t2.join();    printf(" i = %d\n",i);}

T1,t2 there is a possibility of a race condition when two threads are executed concurrently (of course, the probability of a competitive condition is very low, but if you remove the comment, the race condition is very easy to happen)
i++; This statement normally requires 3 machine instructions.

MOV EAX,iINC EAXMOV EAX,i

If executed in the following order, there is no problem, the printed I is 2

Thread 1 Thread 2
MOV Eax,i (i=0)
INC EAX
MOV Eax,i (I=1)
MOV Eax,i (I=1)
INC EAX
MOV Eax,i (i=2)

However, two threads are likely to be executed in the following order, where a race condition appears, and the printed I is 1

Thread 1 Thread 2
MOV Eax,i (i=0)
INC EAX
MOV Eax,i (i=0)
MOV Eax,i (I=1)
INC EAX
MOV Eax,i (I=1)

critical Sections (critical section) are snippets of code that access and manipulate shared resources, as in the case of a two-thread i++ statement

To avoid competitive conditions, the critical section must be executed atomically and cannot be interrupted until the execution is completed. It is common to lock the critical section, use the semaphore, condition variables, and so on, and the simple operations in the example can also use atomic variables.

The understanding of atomic nature

The interpretation of atomicity in general books cannot be interrupted until the end of execution. How is this sentence understood, my personal understanding is:

    • The atomic variable is implemented by means of the lock bus, and several related instructions are executed continuously;
    • Use a lock (spin lock/Sleep Lock), semaphore, condition variable/completion variable these, not that all the commands in the critical section execute continuously, may be executed in the critical section to half, because the scheduling preemption or interrupt, the CPU does not continue in the critical zone execution, that is, execution is interrupted.
      • However, this situation is still guaranteed to avoid competition conditions, because if the process outside the interrupted process is dispatched, the process to access the critical section, the lock or semaphore, etc. "Stop", is not entering the critical area, until the original interrupted critical section execution, release lock/signal volume, etc. Other processes are only likely to enter the critical section.
Causes of concurrency
    • Interrupts: Interrupts can occur asynchronously at almost any moment, and can interrupt code that is currently executing at any time
    • Soft interrupts and Tasklet: The kernel can wake up or dispatch soft interrupts and tasklet at any time, interrupting code that is currently executing
    • Kernel preemption: The Linux kernel is preemptive, so the kernel's task may be preempted by another task
    • Sleep and user space synchronization: Processes that execute in the kernel may sleep and wake up the scheduler
      Scheduler to schedule a new user process execution
    • SMP, two or more processors can execute code at the same time
The synchronization method in the kernel locks

In order to avoid competition conditions, the kernel provides several mechanisms for synchronization, the basic idea is to lock, critical section mutually exclusive access, semaphore can also support more than one thread concurrent access.

Contention for Locks

When it is occupied, there are other threads trying to obtain the lock. The higher the contention of the lock, the lower the system performance (locking can degrade system performance, such as sleep lock, spin lock), but must be used to ensure correctness. To reduce the contention of locks, lock granularity should be as small as possible, that is, the critical area should be as small as possible.

Introduction to several synchronization methods
Synchronization Method Main interface Notes
Atomic integer (32bit) operation atomic_t v;/*定义 v*/
atomic_t u = ATOMIC_INIT(0);/*定义u,初始化为0*/
atomic_set(&v, 4);/* v=4 */
atomic_add(2, &v);/* v=v+2 */
atomic_inc(&v);/* v=v+1 */
Atomic integer (64bit) operation Atomic64_t v;
Atomic bit manipulation unsigned long word = 0; Working with normal pointers
set_bit(0,&word); //第0位被设置 __set_bit in the form of non-atomic operations
set_bit(1,&word); //第1位被设置 Non-atomic operations are faster if atomic operations are not required
printk("%ul\n",word);//打印3 "Linux kernel design and implementation" P147
clear_bit(1,&word);//清空第1位
change_bit(0,&word);//反转第0位
Spin lock DEFINE_SPINLOCK(mr_lock); Spin locks can only be in the critical section at the same time by a single thread
spin_lock(&mr_lock); Provides the protection mechanisms required for concurrent access for multiple processors
/*临界区*/ Single processor, as a kernel preemption whether the switch is turned on, if the kernel preemption is forbidden, compile-time spin lock will be completely rejected the kernel
spin_unlock(&mr_lock); Spin Lock not recursive
Spin lock and Lower half Lower half and process context shared data/lower half and interrupt handler shared data, need to be locked The lower half can preempt the process context, and the interrupt handler can preempt the lower part
Read/write Spin lock DEFINE_RWLOCK(mr_rwlock);
read_lock(&mr_rwlock); shared by all readers
/*临界区(只读)*/
read_unlock(&mr_rwlock);
write_lock(&mr_rwlock); The writer is mutually exclusive, the writer and the reader are mutually exclusive
/*临界区(读写)*/
write_unlock(&mr_rwlock);
Signal Volume struct semophore name; The contention thread sleeps, so the lock can be held for a long time.
sema_init(&name, count); Used in the context of a process
static DECLARE_MUTEX(name);
init_MUTEX(sem) Dynamic initialization of the mutex signal volume
static DECLARE_MUTEX(mr_sem);
if(down_interruptible(&mr_sem)){ /*信号被接收,信号量还未获取*/ }
/*临界区*/
up(&mr_sem);//释放给定的信号量
Read/write signal volume static DECLARE_RWSEM(mr_rwsem); Statically defined
init_rwsem(struct rw_semaphore *sem); Dynamic initialization
down_read(&mr_rwsem);
/*临界区(只读)*/
up_read(&mr_rwsem);
down_write(&mr_rwsem);
/*临界区(读写)*/
up_write(&mr_rwsem);
Mutex DEFINE_MUTEX(name); A sleep lock for handling mutexes
mutex_init(&mutex); Dynamic initialization
mutex_lock(&mutex) Cannot be locked and unlocked in a recursive
/*临界区*/ Can no longer be interrupted or executed in the lower half
mutex_unlock(&mutex)
Completion variables DECLARE_COMPLETION(mr_comp) Wait, know the task is done, send a signal
init_completion(); Dynamically created
Wait for task to be called wait_for_completion();
The task invocation that generated the event Complete ();//Send a signal to wake a specific event

For large kernel lock blk, the contents of the sequential lock are shown in "Linux kernel design and implementation" P160

Prohibit preemption

Kernel preemption code uses spin locks as a token for non-preemption zones
You can disable preemption

A more concise solution to the data access problem on each processor, GET_CPU () Gets the processor number and shuts down the kernel preemption before returning the processor number

int cpu;cpu = get_cpu;//禁止内核抢占,将CPU设置为当前cpu/*对每一个cpu的数据进行操作*/*在给予内核抢占性,“cpu”可改变,所以不再有效*/put_up();
Order and barrier

Reason for order of guarantee

    • When synchronizing problems between multiple processors, hardware devices, you need to read memory and write memory in the program code in the order specified.
    • When interacting with hardware, it is often necessary to ensure that a given read operation precedes other read/write operations
    • On multiple processors, you may need to read the data in the order in which it was written.

For efficiency, the compiler (compilation optimization) and the processor (disorderly execution) may reorder read and write.

    • All CPUs that may be reordered read and write provide machine instructions that are executed sequentially.
    • You can also instruct the compiler not to reorder the sequence of instructions around the given point.
      e.g.
      May reorder
      A=1;
      b=2;
      Impossible to reorder
      A=1;
      B=a;
Explain the reasons for the Order of guarantee

a=1,b=2

Thread 1 Thread 2
A=3;
MB ();
b=4; C=b;
RMB ();
D=a;

If there is no memory barrier on some processors, C may have accepted the new value of B 4,d accepted a original value of 1

Several methods

Full interface List

From the 10th chapter of Linux kernel design and implementation









Linux kernel design and implementation notes--Introduction to Kernel synchronization

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.