This article was transferred from: HTTP://WWW.JIANSHU.COM/P/035550AE05D2
Why concurrency is generated
1. When multiple users log in at the same time, they may call the kernel code in any combination at any time.
2. The SMP system may execute your code on different processors at the same time.
3, Kernel code is preemptive, your program may be stripped of the processor at any time.
4. A device outage can cause concurrent asynchronous events.
5. The kernel also provides various deferred code execution mechanisms, such as task queue and timer, which allows you to run code in a method unrelated to the current process
The impact of concurrency
Concurrency creates competitive conditions, such as two processes accessing the same hardware resources at the same time
The basic principle to be addressed is to avoid sharing data as much as possible
If you can't avoid it, be sure to pay attention to the shared data.
The amount of Linux semaphores
#include <linux/semaphore.h>
/** Copyright (c) Intel corporation* author:matthew Wilcox <[email protected]>** distributed under the terms O f the GNU GPL, version 2** please see kernel/semaphore.c for documentation of thesefunctions*/#Ifndef __linux_semaphore_h#Define __linux_semaphore_h#Include<linux/list.h>#Include<linux/spinlock.h>/* Please don ' t access all members of this structure directly */struct Semaphore {raw_spinlock_t lock;Unsignedint count;struct list_head wait_list;};#Define __semaphore_initializer (name, n) {. Lock = __raw_spin_lock_unlocked ((name). Lock),. Count = N,. wait_list = List_hea D_init ((name). wait_list),} #define DEFINE_SEMAPHORE (name)struct Semaphore name = __semaphore_initializer (name,1)StaticInlinevoid Sema_init (struct Semaphore *sem,int val) {Staticstruct Lock_class_key __key; *sem = (struct semaphore) __semaphore_initializer (*sem, Val); Lockdep_init_map (&sem->lock.dep_map,"Semaphore->lock", &__key,0);}externvoidDown(struct semaphore *sem);externint __Must_checkDown_interruptible(struct semaphore *sem);externint __Must_checkDown_killable(struct semaphore *sem);extern int __must_check down_trylock (struct semaphore *sem); Span class= "Hljs-keyword" >extern int __must_check down_timeout (struct semaphore *sem, long jiffies); extern void up (struct semaphore *sem); #endif /* __LINUX_SEMAPHORE_H */
The down method will reduce the semaphore value by one and wait until the value of the semaphore is greater than or equal to zero to continue execution.
Down_interruptible is similar to down but can be interrupted, it is recommended to use this API, only use down easy to cause the thread will never quit.
The general method of use is:
if (down_interruptible(&sem)) return -ERESTARTSYS;
Read/write signal volume
A common semaphore, for shared files, allows multiple threads to read at the same time, while reading does not allow writing. Only one thread is allowed to write at the same time.
#include <linux/rwsem.h>
Spin lock
The spin lock was originally designed for SMP systems, enabling the protection of critical areas in multi-processor cases.
Spin locks are only two states, locked and unlocked, and are often used to ensure the atomicity of a piece of code
Spinlock API:
void spin_lock(spinlock_t *lock);void spin_lock_irqsave(spinlock_t *lock , unsigned long flags);void spin_lock_irq(spinlock_t *lock);void spin_lock_bh(spinlock_t *lock);
Read/write Spin lock
The Linux kernel provides read-write spin locks, which are actually similar to read and write semaphores.
Requirements for locking
1, if you implement a device lock in your own code, and you want to apply to the Linux kernel to provide locks, please lock your own lock, and then lock the system.
2, if you use the semaphore and spin lock, please first down the semaphore, and then use the spin lock.
3. Ensure that there are no other locks inside the spin lock to prevent the system from being deadlocked.
Linux kernel--concurrent "turn"