1  Terminology supplement

1.1 Privilege

For an operating system , Creating a process is the core function . Creating a process has a lot of work , It will consume a lot of physical resources . Such as allocating physical memory , Copy of parent-child information, etc , All of these require specific processes to do , In this way, there is the concept of special power . The most critical work needs to be handed over to the process with the largest level of authority for centralized management , Reduce access to limited resources and conflicts .inter
x86 Architectural cpu There are four levels ,0-3 level ,0 The highest level of privilege ,3 Level of privilege lowest level .

1.2  User mode and kernel mode

When a process executes the user's own code, it is in the user running state ( User status ), The privilege is the lowest , by 3 level . Is the privilege level for normal user processes to run , Most users directly face the program is run again user mode .R
ing3 State not accessible Ring0 Address space of , Including code and data ; When a process gets stuck in the inner code because of system call, it is in kernel running state ( Kernel state ), At this time, the highest privilege level is 0 level . The kernel code executed uses the kernel stack of the current process , Each process has its own kernel stack .

The user calls a program , The process created by this program will run its own code at the beginning , In user mode . If you want to perform a file operation , Network data sending operation must pass write\send And so on , These system calls call the kernel code . The process switches to Ring0, Then enter 3G-4G To execute the kernel code to complete the corresponding operation . After the kernel state process is executed, it switches to Ring3, Back to user mode . such , The user mode process can not operate the kernel address space at will , It has certain safety protection function . The protection mode refers to the mechanism such as memory page operation , Ensure that the address spaces between processes do not conflict with each other , The operation of one process does not modify the address space data of another process .

1.3  Switching between user mode and kernel mode

When a program is executed in the system , Most of the time it runs in user mode , When it needs the help of the operating system to complete some operations that the user mode does not have the privilege and ability to complete, it will switch to the kernel mode .

* system call

This is a way for user process to switch to kernel mode . The user mode process uses the service program provided by the operating system to complete the work through system call . for example :fork() Is to execute a system call to create a new process . The mechanism and new of system call is realized by using an interrupt specially developed by the operating system for users , as :liunx Of int80h interrupt .

insert :fork Use of
public class Test { static final class SumTask extends RecursiveTask<Integer>
{ private static final long serialVersionUID = 1L; final int start; // Number to start counting
final int end; // Last count SumTask(int start, int end) { this.start = start;
this.end = end; } @Override protected Integer compute() {
// If the calculation amount is less than 1000, Then assign a thread to execute if Code blocks in , And return the execution result if (end - start < 1000) {
System.out.println(Thread.currentThread().getName() + " Start execution :" + start + "-" +
end); int sum = 0; for (int i = start; i <= end; i++) sum += i; return sum; }
// If the calculation amount is greater than 1000, Then split it into two tasks SumTask task1 = new SumTask(start, (start + end) / 2);
SumTask task2 = new SumTask((start + end) / 2 + 1, end); // Carry out the task task1.fork();
task2.fork(); // Get the result of task execution return task1.join() + task2.join(); } } public static
void main(String[] args) throws InterruptedException, ExecutionException {
ForkJoinPool pool = new ForkJoinPool(); ForkJoinTask<Integer> task = new
SumTask(1, 10000); pool.submit(task); System.out.println(task.get()); } }
The results are as follows : ForkJoinPool-1-worker-1 Start execution :1-625 ForkJoinPool-1-worker-7
Start execution :6251-6875 ForkJoinPool-1-worker-6 Start execution :5626-6250 ForkJoinPool-1-worker-10
Start execution :3751-4375 ForkJoinPool-1-worker-13 Start execution :2501-3125 ForkJoinPool-1-worker-8
Start execution :626-1250 ForkJoinPool-1-worker-11 Start execution :5001-5625 ForkJoinPool-1-worker-3
Start execution :7501-8125 ForkJoinPool-1-worker-14 Start execution :1251-1875 ForkJoinPool-1-worker-4
Start execution :9376-10000 ForkJoinPool-1-worker-8 Start execution :8126-8750 ForkJoinPool-1-worker-0
Start execution :1876-2500 ForkJoinPool-1-worker-12 Start execution :4376-5000 ForkJoinPool-1-worker-5
Start execution :8751-9375 ForkJoinPool-1-worker-7 Start execution :6876-7500 ForkJoinPool-1-worker-1
Start execution :3126-3750 50005000
2) abnormal

When cpu When executing a program running in user mode , Something unexpected happened , This will trigger the current running process to switch to the kernel related process handling this exception , That is, switch to kernel mode , If page missing is abnormal .

3) Interruption of peripheral devices

When the peripheral device completes the operation requested by the user , Will to CPU Send out the corresponding interrupt signal , At this time CPU The execution of the next instruction to be executed is suspended and the execution of the handler corresponding to the interrupt signal is performed , If the previously executed instruction is in user mode , Then the process of conversion will naturally be
Switch from user mode to kernel mode . If the hard disk read-write operation is completed , The system will switch to the hard disk read-write interrupt processing program to perform the following operations .

These three modes are the most important way to switch from user mode to kernel mode , The system call can be considered as initiated by the user process , Exceptions and peripheral interruptions are passive . From the trigger mode , The switching mode is different , However, from the actual completion of the switch operation from user mode to kernel mode , The steps are the same , It is equivalent to executing an interrupt response process . System call is actually implemented by interrupt mechanism , The exception and interrupt processing mechanism is basically the same .

2  Terminology supplement

here , Let's see AtomicInteger How to use non blocking algorithm to achieve concurrency control .AtomicInteger There is only one key domain for 3 individual :
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L; // setup to
use Unsafe.compareAndSwapInt for updates private static final Unsafe unsafe =
Unsafe.getUnsafe(); private static final long valueOffset; static { try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value")); } catch (Exception ex) { throw
new Error(ex); } } private volatile int value; /** * Creates a new
AtomicInteger with the given initial value. * * @param initialValue the initial
value */ public AtomicInteger(int initialValue) { value = initialValue; } /** *
Creates a new AtomicInteger with initial value {@code 0}. */ public
AtomicInteger() { } ...... }
here unsafe yes java The class provided to get access to the memory address of the object , Its function is to update the operation time , provide “ Compare and replace ” The role of .V
alueOffset It's for recording value The compiled address of the memory itself , This record is also used to update the operation memory value Location of , Convenient comparison .getAndIncrement This is similar i++ Function of , We can find out , It's called UnSafe Medium getAndAddInt.
/** * Atomically increments by one the current value. * * @return the
previous value */ public final int getAndIncrement() { return
unsafe.getAndAddInt(this, valueOffset, 1); } /** * Atomically sets to the given
value and returns the old value. * * @param newValue the new value * @return
the previous value */ public final int getAndSet(int newValue) { return
unsafe.getAndSetInt(this, valueOffset, newValue); } public final int
getAndSetInt(Object var1, long var2, int var4) { int var5; do { var5 =
this.getIntVolatile(var1, var2); // use unsafe Of native method , Achieve efficient hardware levels CAS }
while(!this.compareAndSwapInt(var1, var2, var5, var4)); return var5; }
How to ensure atomicity : spin + CAS( Optimistic lock ). In the process , adopt compareAndSwapInt Compare and update value value , If the update fails , Get old values again , Then update .

Advantages and disadvantages

      CAS Relative to other locks , Kernel mode operation will not be performed , There are some performance improvements . But spin is introduced at the same time , When lock competition is high , The number of spins will increase .cpu Resource consumption is high . let me put it another way ,CAS+ Spin is suitable for applications with low concurrency and synchronous data .


©2019-2020 Toolsou All rights reserved,
Final review of database : Summary of comprehensive application questions use Python Make simple games Laplance operator ( Second derivative ) Convert hard disk to GPT Partition format Python Implementation of Hanoi Tower code about String How to create objects vue3 Learning journey 1—— establish vue3 project java String from back to front _Java String String summary use Python Write a story about plants versus zombies 【 Greedy Algorithm 】 Huffman coding problem