欢迎来到皮皮网网首页

【thread.start()源码】【最新灰源码】【橙仔源码】park启动源码_spark源码从零开启解析

来源:tp源码 菠菜 时间:2024-12-26 14:06:27

1.ListenableFuture源码解析
2.Rust并发:标准库sync::Once源码分析
3.线程池中空闲的启动启解线程处于什么状态?
4.go源码:Sleep函数与线程
5.Java 中LockSupport类在C#中的实现
6.老生常谈线程基础的几个问题

park启动源码_spark源码从零开启解析

ListenableFuture源码解析

       ListenableFuture 是 spring 中对 JDK Future 接口的扩展,主要应用于解决在提交线程池的源码k源任务拿到 Future 后在 get 方法调用时会阻塞的问题。通过使用 ListenableFuture,零开可以向其注册回调函数(监听器),启动启解当任务完成时,源码k源触发回调。零开thread.start()源码Promise 在 Netty 中也实现了类似的启动启解功能,用于处理类似 Future 的源码k源场景。

       实现 ListenableFuture 的零开关键在于 FutureTask 的源码解析。FutureTask 是启动启解实现 Future 接口的基础类,ListenableFutureTask 在其基础上做了扩展。源码k源其主要功能是零开在任务提交后,当调用 get 方法时能够阻塞当前业务线程,启动启解直到任务完成时唤醒。源码k源

       FutureTask 通过在内部实现一个轻量级的零开 Treiber stack 数据结构来管理等待任务完成的线程。这个数据结构由 WaitNode 节点组成,每个节点代表一个等待的线程。当业务线程调用 get 方法时,会将自己插入到 WaitNode 栈中,并且在插入的同时让当前线程进入等待状态。在任务执行完成后,会遍历 WaitNode 栈,唤醒等待的线程。

       为了确保并发安全,FutureTask 使用 CAS(Compare and Swap)操作来管理 WaitNode 栈。每个新插入的节点都会使用 CAS 操作与栈顶节点进行比较,并在满足条件时更新栈顶。这一过程保证了插入操作的原子性,防止了并发条件下的数据混乱。同时,插入操作与栈顶节点的更新操作相互交织,确保了数据的一致性和完整性。

       在 FutureTask 中,还利用了 LockSupport 类提供的 park 和 unpark 方法来实现线程的等待和唤醒。当线程插入到 WaitNode 栈中后,通过 park 方法将线程阻塞;任务执行完成后,通过 unpark 方法唤醒线程,完成等待与唤醒的流程。

       综上所述,ListenableFuture 通过扩展 FutureTask 的功能,实现了任务执行与线程等待的高效管理。通过注册监听器并利用 CAS 操作与 LockSupport 方法,实现了在任务完成时通知回调,解决了异步任务执行时的线程阻塞问题,提高了程序的并发处理能力。

Rust并发:标准库sync::Once源码分析

       一次初始化同步原语Once,其核心功能在于确保闭包仅被执行一次。常见应用包括FFI库初始化、静态变量延迟初始化等。

       标准库中的Once实现更为复杂,其关键在于如何高效地模拟Mutex阻塞与唤醒机制。这一机制依赖于线程暂停和唤醒原语thread::park/unpark,它们是实现多线程同步对象如Mutex、Condvar等的基础。

       具体实现中,Once维护四个内部状态,状态与等待队列头指针共同存储于AtomicUsize中,利用4字节对齐优化空间。

       构造Once实例时,初始化状态为Incomplete。调用Once::call_once或Once::call_once_force时,分别检查是否已完成初始化,未完成则执行闭包,闭包执行路径标记为冷路径以节省资源,最新灰源码同时避免泛型导致的代码膨胀。

       闭包执行逻辑由Once::call_inner负责,线程尝试获取执行权限,未能获取则进入等待状态,获取成功后执行闭包,结束后唤醒等待线程。

       等待队列通过无锁侵入式链表实现,节点在栈上分配,以优化内存使用。Once::wait函数实现等待线程逻辑,WaiterQueue的drop方法用于唤醒所有等待线程,需按特定顺序操作栈节点,以避免use after free等潜在问题。

       思考题:如何在实际项目中利用Once实现资源安全共享?如何评估Once与Mutex等同步原语在不同场景下的性能差异?

线程池中空闲的线程处于什么状态?

       一:阻塞状态,线程并没有销毁,也没有得到CPU时间片执行;

       源码追踪:

       for (;;) {

       ...

        workQueue.take();

       ...

       }

       public E take()...{

       ...

       while (count.get() == 0) { / /这里就是任务队列中的消息数量

       notEmpty.await();

       }

       ...

       }

       public final void await()...{

       ...

       LockSupport.park(this);

       ...

       }

       继续往下:

       public static void park(Object blocker) {

       Thread t = Thread.currentThread();

       setBlocker(t, blocker);

       U.park(false, 0L);

       setBlocker(t, null);

       }

       private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();

       //线程调用该方法,线程将一直阻塞直到超时,或者是中断条件出现。

       public native void park(boolean isAbsolute, long time);

       上面就是java线程池中阻塞的源码追踪;

       二.对比object的wait()方法:

       @FastNative

       public final native void wait(long timeout, int nanos) throws InterruptedException;

       还有Thread的sleep() 方法:

       @FastNative

       private static native void sleep(Object lock, long millis, int nanos)throws...;

       可见,线程池中使用的阻塞方式并不是Object中的wait(),也不是Thread.sleep() ;

       这3个方法最终实现都是通过c&c++实现的native方法.

       三.在<<Java虚拟机(第二版)>>中,对线程状态有以下介绍:

       .4.3 状态转换

       Java语言定义了5种线程状态,在任意一个时间点,一个线程只能有且只有其中的一种

       状态,这5种状态分别如下。

       1)新建(New):创建后尚未启动的线程处于这种状态。

       2)运行(Runable):Runable包括了操作系统线程状态中的Running和Ready,也就是处于此

       状态的线程有可能正在执行,也有可能正在等待着CPU为它分配执行时间。

       3)无限期等待(Waiting):处于这种状态的线程不会被分配CPU执行时间,它们要等待被

       其他线程显式地唤醒。以下方法会让线程陷入无限期的等待状态:

       ●没有设置Timeout参数的Object.wait()方法。

       ●没有设置Timeout参数的Thread.join()方法。

       ●LockSupport.park()方法。

       4)限期等待(Timed Waiting):处于这种状态的线程也不会被分配CPU执行时间,不过无

       须等待被其他线程显式地唤醒,在一定时间之后它们会由系统自动唤醒。以下方法会让线程

       进入限期等待状态:

       ●Thread.sleep()方法。

       ●设置了Timeout参数的Object.wait()方法。

       ●设置了Timeout参数的Thread.join()方法。

       ●LockSupport.parkNanos()方法。

       ●LockSupport.parkUntil()方法。

       5)阻塞(Blocked):线程被阻塞了,“阻塞状态”与“等待状态”的区别是:“阻塞状态”在等

       待着获取到一个排他锁,这个事件将在另外一个线程放弃这个锁的时候发生;而“等待状

       态”则是在等待一段时间,或者唤醒动作的发生。在程序等待进入同步区域的时候,线程将

       进入这种状态。

       结束(Terminated):已终止线程的线程状态,线程已经结束执行。

go源码:Sleep函数与线程

       在探索 Go 语言的并发编程中,Sleep 函数与线程的交互方式与 Java 或其他基于线程池的并发模型有所不同。本文将深入分析 Go 语言中 Sleep 函数的实现及其与线程的互动方式,以解答关于 Go 语言中 Sleep 函数与线程关系的问题。

       首先,重要的一点是,当一个 goroutine(g)调用 Sleep 函数时,它并不会导致当前线程被挂起。相反,Go 通过特殊的机制来处理这种情景,确保 Sleep 函数的调用不会影响到线程的执行。这一特性是 Go 语言并发模型中独特而关键的部分。

       具体来说,当一个 goroutine 调用 Sleep 函数时,它首先将自身信息保存到线程的关键结构体(p)中并挂起。这一过程涉及多个函数调用,包括 `time.Sleep`、`runtime.timeSleep`、橙仔源码`runtime.gopark`、`runtime.mcall`、`runtime.park_m`、`runtime.resetForSleep` 等。最终,该 goroutine 会被放入一个 timer 结构体中,并将其放入到 p 关联的一个最小堆中,从而实现了对当前 goroutine 的保存,同时为调度器提供了切换到其他 goroutine 或 timer 的机会。因此,这里的 timer 实际上代表了被 Sleep 挂起的 goroutine,它在睡眠到期后能够及时得到执行。

       接下来,我们深入分析 goroutine 的调度过程。当线程 p 需要执行时,它会通过 `runtime.park_m` 函数调用 `schedule` 函数来进行 goroutine 或 timer 的切换。在此过程中,`runtime.findrunnable` 函数会检查线程堆中是否存在已到期的 timer,如果存在,则切换到该 timer 进行执行。如果 timer 堆中没有已到期的 timer,线程会继续检查本地和全局的 goroutine 队列中是否还有待执行的 goroutine,如果队列为空,则线程会尝试“偷取”其他 goroutine 的任务。这一过程包括了检查 timer 堆、偷取其他 p 中的到期 timer 或者普通 goroutine,确保任务能够及时执行。

       在“偷取”任务的过程中,线程会优先处理即将到期的 timer,确保这些 timer 的准时执行。如果当前线程正在执行其他任务(如 epoll 网络),则在执行过程中会定期检查 timer 到期情况。如果发现其他线程的 timer 到期时间早于自身,会首先唤醒该线程以处理其 timer,确保不会错过任何到期的 timer。

       为了证明当前线程设置的 timer 能够准时执行,本文提出了两种证明方法。第一种方法基于代码细节,重点分析了线程状态的变化和 timer 的执行流程。具体而言,文章中提到的三种线程状态(正常运行、epoll 网络、睡眠)以及相应的 timer 执行情况,表明在 Go 语言中,timer 的执行策略能够确保其准时执行。第二种方法则从全局调度策略的角度出发,强调了 Go 语言中线程策略的设计原则,即至少有一个线程处于“spinning”状态或者所有线程都在执行任务,这保证了 timer 的准时执行。

       总之,Go 语言中 Sleep 函数与线程之间的交互方式,通过特殊的线程管理机制,确保了 goroutine 的 Sleep 操作不会阻塞线程,同时保证了 timer 的准时执行。这一机制是 Go 语言并发模型的独特之处,为开发者提供了一种高效且灵活的并发处理方式。

Java 中LockSupport类在C#中的实现

          Java 之后提供优秀的并发库ncurrent Net中缺乏类似的功能 由于硬件体系发生了变化 多核时代来临 NET中缺乏并发类库显然不合时宜 缓解这一矛盾的其中一个办法就是在往C#中移植java的ncurrent

          java中的ncurrent包中提供了一个类LockSupport ncurrent包很多关键实现需要调用LockSupport 如果需要把java的ncurrent包迁移到C#中 LockSupport类的迁移是不可避免的问题

          在java中 LockSupport类有如下方法

          以下是引用片段

          

       

          public static void park(Object blocker) {   Thread t = Thread currentThread();   setBlocker(t  blocker);   unsafe park(false   L);   setBlocker(t  null);   }

          当一个线程调用LockSupport park之后 线程就会停下载 类似于Object wait 或者 NET中的System Threading Monitor Wait 但问题是java中的Object wait和 NET中的Monitor wait 都需要一个waitObject 这个问题曾经困扰我 为此翻了一遍JDK 实现源码 到最后发现的解决办法却是很简单 也无需了解JDK的底层实现源码

          以下是引用片段

          

          public class LockSupport   {   private static LocalDataStoreSlot slot = Thread GetNamedDataSlot ( LockSupport Park );   public static void Park(Object blocker)   {   Thread thread = Thread CurrentThread;   Thread SetData(slot  blocker);   lock (thread)   {   Monitor Wait(thread);   }   }   public static void Unpark(Thread thread)   {   if (thread == null) return;   lock (thread)   {   Monitor Pulse(thread);   }   }   }

lishixinzhi/Article/program/net//

老生常谈线程基础的几个问题

       实现线程只有一种方式

       我们知道启动线程至少可以通过以下四种方式:

       实现Runnable接口

       继承Thread类

       线程池创建线程

       带返回值的Callable创建线程

       但是看它们的底层就一种方式,就是通过newThread()实现,其他的只不过在它的上面做了层封装。

       实现Runnable接口要比继承Thread类的更好:

       结构上分工更明确,线程本身属性和任务逻辑解耦。

       某些情况下性能更好,直接把任务交给线程池执行,醉江湖源码无需再次newThread()。

       可拓展性更好:实现接口可以多个,而继承只能单继承。

       有的时候可能会问到启动线程为什么是start()方法,而不是run()方法,这个问题很简单,执行run()方法其实就是在执行一个类的普通方法,并没有启动一个线程,而start()方法点进去看是一个native方法。

       当我们在执行java中的start()方法的时候,它的底层会调JVM由c++编写的代码Thread::start,然后c++代码再调操作系统的create_thread创建线程,创建完线程以后并不会马上运行,要等待CPU的调度。CPU的调度算法有很多,比如先来先服务调度算法(FIFO),最短优先(就是对短作业的优先调度)、时间片轮转调度等。如下图所示:

线程的状态

       在Java中线程的生命周期中一共有6种状态。

       NEW:初始状态,线程被构建,但是还没有调用start方法

       RUNNABLE:运行状态,JAVA线程把操作系统中的就绪和运行两种状态统一称为运行中

       BLOCKED:阻塞状态,表示线程进入等待状态,也就是线程因为某种原因放弃了CPU使用权

       WAITING:等待状态

       TIMED_WAITING:超时等待状态,超时以后自动返回

       TERMINATED:终止状态,表示当前线程执行完毕

       当然这也不是我说的,源码中就是这么定义的:

publicenumState{ /***Threadstateforathreadwhichhasnotyetstarted.*/NEW,/***Threadstateforarunnablethread.Athreadintherunnable*stateisexecutingintheJavavirtualmachinebutitmay*bewaitingforotherresourcesfromtheoperatingsystem*suchasprocessor.*/RUNNABLE,/***Threadstateforathreadblockedwaitingforamonitorlock.*Athreadintheblockedstateiswaitingforamonitorlock*toenterasynchronizedblock/methodor*reenterasynchronizedblock/methodaftercalling*{ @linkObject#wait()Object.wait}.*/BLOCKED,/***Threadstateforawaitingthread.*Athreadisinthewaitingstateduetocallingoneofthe*followingmethods:*<ul>*<li>{ @linkObject#wait()Object.wait}withnotimeout</li>*<li>{ @link#join()Thread.join}withnotimeout</li>*<li>{ @linkLockSupport#park()LockSupport.park}</li>*</ul>**<p>Athreadinthewaitingstateiswaitingforanotherthreadto*performaparticularaction.**Forexample,athreadthathascalled<tt>Object.wait()</tt>*onanobjectiswaitingforanotherthreadtocall*<tt>Object.notify()</tt>or<tt>Object.notifyAll()</tt>on*thatobject.Athreadthathascalled<tt>Thread.join()</tt>*iswaitingforaspecifiedthreadtoterminate.*/WAITING,/***Threadstateforawaitingthreadwithaspecifiedwaitingtime.*Athreadisinthetimedwaitingstateduetocallingoneof*thefollowingmethodswithaspecifiedpositivewaitingtime:*<ul>*<li>{ @link#sleepThread.sleep}</li>*<li>{ @linkObject#wait(long)Object.wait}withtimeout</li>*<li>{ @link#join(long)Thread.join}withtimeout</li>*<li>{ @linkLockSupport#parkNanosLockSupport.parkNanos}</li>*<li>{ @linkLockSupport#parkUntilLockSupport.parkUntil}</li>*</ul>*/TIMED_WAITING,/***Threadstateforaterminatedthread.*Thethreadhascompletedexecution.*/TERMINATED;}

       下面是这六种状态的转换:

New新创建

       New表示线程被创建但尚未启动的状态:当我们用newThread()新建一个线程时,如果线程没有开始调用start()方法,那么此时它的状态就是New。而一旦线程调用了start(),它的状态就会从New变成Runnable。

Runnable运行状态

       Java中的Runable状态对应操作系统线程状态中的两种状态,分别是Running和Ready,也就是说,Java中处于Runnable状态的线程有可能正在执行,也有可能没有正在执行,正在等待被分配CPU资源。

       如果一个正在运行的线程是Runnable状态,当它运行到任务的一半时,执行该线程的CPU被调度去做其他事情,导致该线程暂时不运行,它的状态依然不变,还是Runnable,因为它有可能随时被调度回来继续执行任务。

       在Java中Blocked、Waiting、TimedWaiting,这三种状态统称为阻塞状态,下面分别来看下。

Blocked

       从上图可以看出,从Runnable状态进入Blocked状态只有一种可能,就是进入synchronized保护的代码时没有抢到monitor锁,jvm会把当前的线程放入到锁池中。当处于Blocked的线程抢到monitor锁,就会从Blocked状态回到Runnable状态。

Waiting状态

       我们看上图,线程进入Waiting状态有三种可能。

       没有设置Timeout参数的Object.wait()方法,jvm会把当前线程放入到等待队列。

       没有设置Timeout参数的Thread.join()方法。

       LockSupport.park()方法。

       Blocked与Waiting的区别是Blocked在等待其他线程释放monitor锁,而Waiting则是优发卡源码在等待某个条件,比如join的线程执行完毕,或者是notify()/notifyAll()。

       当执行了LockSupport.unpark(),或者join的线程运行结束,或者被中断时可以进入Runnable状态。当调用notify()或notifyAll()来唤醒它,它会直接进入Blocked状态,因为唤醒Waiting状态的线程能够调用notify()或notifyAll(),肯定是已经持有了monitor锁,这时候处于Waiting状态的线程没有拿到monitor锁,就会进入Blocked状态,直到执行了notify()/notifyAll()唤醒它的线程执行完毕并释放monitor锁,才可能轮到它去抢夺这把锁,如果它能抢到,就会从Blocked状态回到Runnable状态。

TimedWaiting状态

       在Waiting上面是TimedWaiting状态,这两个状态是非常相似的,区别仅在于有没有时间限制,TimedWaiting会等待超时,由系统自动唤醒,或者在超时前被唤醒信号唤醒。

       以下情况会让线程进入TimedWaiting状态。

       设置了时间参数的Thread.sleep(longmillis)方法。

       设置了时间参数的Object.wait(longtimeout)方法。

       设置了时间参数的Thread.join(longmillis)方法。

       设置了时间参数的LockSupport.parkNanos(longnanos)。

       LockSupport.parkUntil(longdeadline)方法。

       在TimedWaiting中执行notify()和notifyAll()也是一样的道理,它们会先进入Blocked状态,然后抢夺锁成功后,再回到Runnable状态。当然,如果它的超时时间到了且能直接获取到锁/join的线程运行结束/被中断/调用了LockSupport.unpark(),会直接恢复到Runnable状态,而无需经历Blocked状态。

Terminated终止

       Terminated终止状态,要想进入这个状态有两种可能。

       run()方法执行完毕,线程正常退出。

       出现一个没有捕获的异常,终止了run()方法,最终导致意外终止。

线程的停止interrupt

       我们知道Thread提供了线程的一些操作方法,比如stop(),suspend()和resume(),这些方法已经被Java直接标记为@Deprecated,这就说明这些方法是不建议大家使用的。

       因为stop()会直接把线程停止,这样就没有给线程足够的时间来处理想要在停止前保存数据的逻辑,任务戛然而止,会导致出现数据完整性等问题。这种行为类似于在linux系统中执行kill-9类似,它是一种不安全的操作。

       而对于suspend()和resume()而言,它们的问题在于如果线程调用suspend(),它并不会释放锁,就开始进入休眠,但此时有可能仍持有锁,这样就容易导致死锁问题,因为这把锁在线程被resume()之前,是不会被释放的。

interrupt

       最正确的停止线程的方式是使用interrupt,但interrupt仅仅起到通知被停止线程的作用。而对于被停止的线程而言,它拥有完全的自主权,它既可以选择立即停止,也可以选择一段时间后停止,也可以选择压根不停止。

       下面我们来看下例子:

publicclassInterruptExampleimplementsRunnable{ //interrupt相当于定义一个volatile的变量//volatilebooleanflag=false;publicstaticvoidmain(String[]args)throwsInterruptedException{ Threadt1=newThread(newInterruptExample());t1.start();Thread.sleep(5);//Main线程来决定t1线程的停止,发送一个中断信号,中断标记变为truet1.interrupt();}@Overridepublicvoidrun(){ while(!Thread.currentThread().isInterrupted()){ System.out.println(Thread.currentThread().getName()+"--");}}}

       执行一下,运行了一会就停止了

       主线程在调用t1的interrupt()之后,这个线程的中断标记位就会被设置成true。每个线程都有这样的标记位,当线程执行时,会定期检查这个标记位,如果标记位被设置成true,就说明有程序想终止该线程。在while循环体判断语句中,通过Thread.currentThread().isInterrupt()判断线程是否被中断,如果被置为true了,则跳出循环,线程就结束了,这个就是interrupt的简单用法。

阻塞状态下的线程中断

       下面来看第二个例子,在循环中加了Thread.sleep秒。

publicclassInterruptSleepExampleimplementsRunnable{ //interrupt相当于定义一个volatile的变量//volatilebooleanflag=false;publicstaticvoidmain(String[]args)throwsInterruptedException{ Threadt1=newThread(newInterruptSleepExample());t1.start();Thread.sleep(5);//Main线程来决定t1线程的停止,发送一个中断信号,中断标记变为truet1.interrupt();}@Overridepublicvoidrun(){ while(!Thread.currentThread().isInterrupted()){ try{ Thread.sleep();}catch(InterruptedExceptione){ //中断标记变为falsee.printStackTrace();}System.out.println(Thread.currentThread().getName()+"--");}}}

       再来看下运行结果,卡主了,并没有停止。这是因为main线程调用了t1.interrupt(),此时t1正在sleep中,这时候是接收不到中断信号的,要sleep结束以后才能收到。这样的中断太不及时了,我让你中断了,你缺还在傻傻的sleep中。

       Java开发的设计者已经考虑到了这一点,sleep、wait等方法可以让线程进入阻塞的方法使线程休眠了,而处于休眠中的线程被中断,那么线程是可以感受到中断信号的,并且会抛出一个InterruptedException异常,同时清除中断信号,将中断标记位设置成false。

       这时候有几种做法:

       直接捕获异常,不做处理,e.printStackTrace();打印下信息

       将异常往外抛出,即在方法上throwsInterruptedException

       再次中断,代码如下,加上Thread.currentThread().interrupt();

@Overridepublicvoidrun(){ while(!Thread.currentThread().isInterrupted()){ try{ Thread.sleep();}catch(InterruptedExceptione){ //中断标记变为falsee.printStackTrace();//把中断标记修改为trueThread.currentThread().interrupt();}System.out.println(Thread.currentThread().getName()+"--");}}

       这时候线程感受到了,我们人为的再把中断标记修改为true,线程就能停止了。一般情况下我们操作线程很少会用到interrupt,因为大多数情况下我们用的是线程池,线程池已经帮我封装好了,但是这方面的知识还是需要掌握的。感谢收看,多多点赞~

       作者:小杰博士

华为openEuler.版本怎么样

       华为 openEuler .是华为发布的全新创新桌面选择。该版本属于全新的创新版本而不是 LTS (Long Term Support) 版本。全新的创新桌面为用户们带来的是更强的虚拟化功能和更多桌面选择支持。

       华为 openEuler .介绍

全新的5.内核

       1、深度优化调度、IO、内存管理,提供Arm、x、RISC-V等更多计算能力支持。

       2、对调度程序进行了优化,以优化CFS任务的公平性,并添加了感知numa的异步调用机制,这在NVDIMM初始化方面有了显著的改进;优化了SCHED_IDLE的调度策略,显著提高了高优先级任务的调度延迟,降低了其他任务干扰的成本。

       3、numa平衡机制的优化带来了更好的亲和性、更高的利用率和更少的无效迁移。

       4、增强CPU隔离机制,支持中断隔离,支持非绑定线程隔离,增强CPU内核隔离,更好地避免业务间相互干扰。

       5、优化了cgroup单线程迁移的性能,消除了对线程组读写信号量的依赖;时间名称空间的引入使得容器迁移更加方便。

       6、系统容器支持限制容器中使用的文件句柄的数量。文件句柄包括普通的文件句柄和网络套接字。在启动容器时,可以指定——files-limit参数来限制容器中打开句柄的最大数量。

       7、PSI能力支持。PSI (Pressure Stall Information)提供了一种评估系统资源(如CPU、内存和IO)压力的方法。准确的检测方法可以帮助资源用户确定合适的工作量,也可以帮助系统制定高效的资源调度策略,最大限度地利用系统资源,最大限度地提高用户体验。

       8、进程间通信优化,pipe/epoll_wait唤醒机制优化,解决唤醒多个等待线程的性能问题。

       9、增强内存管理、细化内存控制、统计、异构内存、热插拔、内存初始化等功能得到了改进,并提供了更有效的用户控制界面;热点锁和信号量优化,激进的内存调节和碎片整理,优化、vmap/vmalloc机制,显著提高内存应用效率;KASAN, kmemleak, slub_debug, oom和其他内存维护功能都得到了增强,以提高内存问题的定位和解决效率。

       、提前发包时间模式开关解决了原有TCP框架在报文发送过程中的局限性。根据调度策略,为数据包设置EDT时间戳,避免了队列缓冲区过大造成的延迟,从而大大提高了TCP的性能。

       、支持多路径TCP,可以提高移动和数据场景下的性能和可靠性,支持负载均衡场景下多个子流并行传输。

       、引入了log fast commit方法,而EXT4引入了一种新的、更轻量级的日志记录方法——fast commit,它可以极大地加快耗时的操作,比如fsync,并带来更好的性能。

       、支持dm写cache特性,提高SSD大容量顺序写性能,提高DDR持久化内存性能。

       、io_uring是一个新的异步IO框架和实现,支持轮询模式。在轮询模式下,性能得到了与spdk类似的显著提高,队列深度越高,性能越好。

       、支持ILP,在鲲鹏 Arm环境下支持位应用程序。

       、IMA商业增强,基于开源IMA解决方案,增强安全性,提高性能,提高易用性,并帮助商业实现。

       、支持单任务栈巡检,增强对ROP攻击的防范能力。

       、MPAM资源管理和控制,支持Arm架构的缓存QoS和内存带宽控制技术。

       、支持基于sedim的NMI机制和基于pmu的NMI机制,实现硬锁检测;启用perf nmi可以实现更准确的性能分析。

       、Arm平台支持虚拟机CPU热插拔,提高了资源配置的灵活性。

       、Arm kdump得到了增强,支持4G以上地址的内存预留,这样kdump可以预留更多的内存空间,并支持具有更大内存的机器。

       、支持树莓派系列板。Raspberry Pi的支持已经集成到本地的openEuler .内核中,可以直接使用openEuler .内核源代码进行调试。

       、RISC-V平台支持KVM虚拟化。

       、支持智能网卡。

热内核升

       1、热内核升级是修复和升级操作系统漏洞的解决方案。实现了无服务意识的内核快速热替换。

       2、Cpu Park和Quick Kexec的功能加速系统启动和停止,减少停机时间,提高系统可用性。

       3、Pin存储器和Pmem功能可确保快速准确地恢复业务流程,并提高业务灵活性。

       4、内核热升级控制器提供gRPC通讯接口,使用方便。

内存分层

       1、支持多内存和存储介质的统一管理,支持系统容量的平滑扩展。

       2、冷热页识别,通过内核态内存页的空闲和空闲统计机制,准确识别进程内存页访问的冷热分布。

       3、可以配置淘汰策略,提供配置界面,自定义内存页面冷热分类策略。

       4、平滑扩展,冷页自动切换到扩展内存,其上部署的软件兼容运行,无需改变或调整编程模式。

       5、支持多媒体扩展,支持单片机、XL Flash、NVMe SSD等介质作为扩展内存,并根据介质本身的访问速度指定冷热内存分层方案,以达到扩展内存、降低性能损失的目的。

       6、增强的虚拟化能力和可维护的测量能力。

       7、增加了热迁移Pro的能力扩展,提高了可维护性和可测性。

       8、热迁移专业版功能,增强热迁移多功能支持TLS,确保迁移过程中的数据安全;支持热迁移数据的并行压缩,提高迁移性能;增加数据页面访问频率的统计,支持热迁移数据的早期预测。

       9、vmtop性能调试工具可以实时动态查看虚拟机的资源使用情况,包括CPU占用率、内存占用率等信息。增加了支持x_架构的扩展。

       、支持IO挂起。默认情况下,当发生io错误时,IO会自动重试,超时后会报告警报。

       、RISC-V架构支持虚拟化热迁移。

轻量级虚拟运行

       1、添加灵活的内存,大页面功能,系统调用过滤功能,增强IO子系统,提高性能和稳定性。

       2、灵活的内存支持,根据工作负载的内存需求实现内存分配和恢复,virtio-balloon的内存恢复速度可达3GB/s。

       3、大页面支持。在轻量级框架中提供大页面支持,可以为轻量级虚拟机提供连续的物理内存页面,提高虚拟机的内存访问效率。

       4、系统调用过滤简化了设备模型,增加了对系统调用过滤的支持,只需要最简单配置的个系统调用,有效减少了系统攻击面。

       5、输入输出子系统得到增强,以支持多通道并发输入输出能力并提高性能。支持IO- qos能力,增强虚拟机IO流量管理的灵活性和稳定性。open stack 维多利亚集成。

       6、简单、可扩展、丰富、统一的云管理操作系统。更多功能见OpenStack Victoria官方发行说明。

       7、通过集成openStack Vicoria版本实现IaaS(基础设施即服务)解决方案。

       8、增强数据块存储的服务能力,并添加容量扩展、快照和虚拟机映像克隆等高级功能。

       9、增强集装箱化部署和网络能力,以便更好地与集装箱集成。

       、添加扩展服务支持,并支持扩展服务,如控制面板管理、裸机部署和云资源跟踪。

Kubernetes 1.集成

       1、有关云本机操作系统自动部署、扩展和管理容器化应用程序的更多功能,请参考Kubernetes 1.的官方发行说明。

       2、自动联机和回滚。Kubernetes会自动将应用程序或其配置更改的实例联机,并监控应用程序的运行状态。如果失败,将回滚以前的更改。

       3、服务发现和负载均衡,支持基于容器IP和DNS名称的服务发现和负载均衡。

       4、存储业务流程支持自动挂载多个存储后端,如本地存储、NFS、iSCSI、Gluster、Ceph等网络存储系统。

       5、水平扩展,支持命令行扩展,用户界面手动扩展,根据CPU占用率自动扩展。