4.线程到底是如何调度和切换的?

本文深入探讨了Windows内核线程调度的过程,通过分析`NtYieldExecution`函数,展示了线程如何主动让出CPU并进行调度。讲解了`KiSelectReadyThread`函数如何选择最高优先级的线程,并介绍了`KiComputeNewPriority`函数如何根据线程状态调整优先级。此外,还阐述了线程调度的原则,包括优先级严格调度、时间片分配和抢占策略等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.线程到底是如何调度和切换的?

本节内容将作为本篇文章最重要的部分来讲述,源代码才是我们的王道,在WRK-v1.2\base\ntos\ke\Yield.c文件里,我们终于看到代码了,需要说明的是这个部分并非是完整的调度,我们是从这个入手来看整个的过程,没有源代码的原理就是空中楼阁。

NTSTATUS  NtYieldExecution (VOID)

{

    KIRQL OldIrql;

    PKTHREAD NewThread;

    PRKPRCB Prcb;

    NTSTATUS Status;

    PKTHREAD Thread;

 

    if (KiGetCurrentReadySummary() ==0) {      //如果当前CPU没有就绪线程

        return STATUS_NO_YIELD_PERFORMED;

 

    } else {

        Status =STATUS_NO_YIELD_PERFORMED;

        Thread =KeGetCurrentThread(); //获取当前线程

        OldIrql =KeRaiseIrqlToSynchLevel();//将运行级别提高到DISPATCH_LEVEL级别

        Prcb = KeGetCurrentPrcb();//获取重要的PRCB机构

        if (Prcb->ReadySummary !=0) {    //如果有就绪线程  

           KiAcquireThreadLock(Thread);//锁定当前线程

           KiAcquirePrcbLock(Prcb);//锁定当前PRCB

            if (Prcb->NextThread== NULL) {

                Prcb->NextThread =KiSelectReadyThread(1, Prcb);

            }    //如果没有线程准备好运行的话就向前找下一个可以运行的线程

            if ((NewThread =Prcb->NextThread) != NULL) {

                Thread->Quantum =Thread->QuantumReset;    //前面讲了很久的时限了,看到源代码的时候还是惊喜了一些

                Thread->Priority =KiComputeNewPriority(Thread, 1);    //这里很有趣哦,下面会专门讲这个函数的。   

               KiReleaseThreadLock(Thread);//释放线程锁

               KiSetContextSwapBusy(Thread);//将SwapBusy设置成TURE

 

         &nbs

<think>嗯,用户问了五个问题,都是关于并发并行的。我需要逐一分析每个问题,并给出准确的回答。首先,用户可能是在学习编程或者系统设计,对并发处理有深入兴趣,可能在开发多线程或异步应用时遇到了问题。 第一个问题,关于并发与并行的具体技术差异。我需要明确两者定义,技术实现上的不同,比如并发是交替执行,而并行是同时执行。还要提到单核多核的区别,以及适用场景。 第二个问题,用Python实现多线程并发。Python的threading模块是基础,但要注意GIL的影响。可能需要举例子,比如启动多个线程,使用join等待结束。另外,用户可能知道GIL会限制多线程性能,是否需要提到替代方案如multiprocessing? 第三个问题,锁机制类型。这里要列出常见的锁,比如互斥锁、读写锁、信号量等,并解释它们的用途区别。例如,互斥锁保护共享资源,读写锁允许多个读操作等。 第四个问题,异步编程与回调地狱的解决。需要解释回调地狱是什么,如何通过协程、async/await或者Promise链来解决。Python中的asyncio库async/await语法是关键点。 第五个问题,操作系统如何调度并发任务。涉及调度算法,比如时间片轮转、优先级调度,以及上下文切换的过程。还要提到调度器的作用不同系统的实现差异。 需要确保每个回答简明扼要,技术术语准确,同时提供示例或具体方法。用户可能希望得到实践指导,所以代码示例会有帮助。此外,相关问题可能需要引导用户进一步探索相关主题,如死锁避免、异步库的使用等。</think>### 1. 并发与并行的具体技术差异是什么? 并发(Concurrency)并行(Parallelism)的核心差异体现在**任务执行方式****硬件依赖**上: - **执行逻辑**: - **并发**:单核CPU通过快速切换任务(时间片轮转)模拟多任务同时执行(如单线程处理多个I/O请求)。 - **并行**:多核CPU真正同时执行多个任务(如多线程计算密集型任务)。 - **资源共享**: - 并发任务共享同一资源(如单核CPU),需通过调度器协调;并行任务通常独立占用物理资源(如多核CPU)。 - **典型场景**: - 并发适用于I/O密集型任务(如Web服务器处理请求);并行适用于计算密集型任务(如科学计算、图像渲染)。 --- ### 2. 如何用Python实现多线程并发? Python通过`threading`模块实现多线程,但需注意全局解释器锁(GIL)限制: ```python import threading def worker(): print("Thread running") # 创建线程 threads = [threading.Thread(target=worker) for _ in range(5)] # 启动线程 for t in threads: t.start() # 等待所有线程完成 for t in threads: t.join() ``` **注意事项**: - GIL导致多线程无法利用多核CPU优势,适合I/O密集型任务(如网络请求)。 - 计算密集型任务建议使用`multiprocessing`模块实现多进程。 --- ### 3. 并发模型中的锁机制有哪些类型? 常见锁机制及其适用场景: | 锁类型 | 特点与用途 | |----------------|----------------------------------------| | **互斥锁(Mutex)** | 最基础的锁,同一时刻仅允许一个线程访问资源(如保护共享变量)。 | | **读写锁(Read-Write Lock)** | 允许多个读线程同时访问,但写线程独占资源(如缓存读写场景)。 | | **信号量(Semaphore)** | 控制同时访问的线程数量(如资源池限流)。 | | **自旋锁(Spinlock)** | 线程忙等待而非阻塞,适用于锁持有时间极短的场景。 | | **条件变量(Condition Variable)** | 结合互斥锁实现线程间通知机制(如生产者-消费者模型)。 | --- ### 4. 异步编程与回调地狱如何解决? **回调地狱(Callback Hell)** 是嵌套回调导致代码难以维护的问题,解决方案包括: - **协程(Coroutines)**:通过`async/await`语法简化异步流程(如Python的`asyncio`): ```python import asyncio async def fetch_data(): print("Fetching data...") await asyncio.sleep(1) return "Data" async def main(): result = await fetch_data() print(result) asyncio.run(main()) ``` - **Promise/Future**:通过链式调用替代嵌套(如JavaScript的`Promise.then()`)。 - **反应式编程**:使用Rx库(如RxPy)通过流式处理异步事件。 --- ### 5. 操作系统如何调度并发任务? 操作系统调度器通过以下机制管理并发任务: 1. **调度算法**: - **时间片轮转(Round Robin)**:为每个任务分配固定时间片,超时则切换任务。 - **优先级调度**:高优先级任务抢占低优先级任务的CPU时间(如实时任务优先)。 - **多级反馈队列**:根据任务行为动态调整优先级(如I/O密集型任务优先)。 2. **上下文切换**:保存当前任务寄存器状态到内存,加载下一个任务的状态。 3. **中断处理**:硬件中断(如I/O完成)触发调度器重新选择任务。 4. **资源隔离**:通过虚拟内存权限控制防止任务间相互干扰。 **示例**:Linux使用完全公平调度器(CFS),通过红黑树管理任务优先级,确保每个任务获得公平CPU时间。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值