记录:2022-9-3 动态规划 滑动窗口 操作系统线程调度

学习时间 2022-9-3

学习内容

1、LeetCode 两道中等题

无重复字符的最长子串

在这里插入图片描述
b站的模板:
在这里插入图片描述
做了一道题,目前的感觉是,不知道这个mx放哪里,什么时候去修改,可能需要根据不同的题目选取?

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int L = 0;
        int R = 0;
        int mx = 0;
        HashSet<Character> set = new HashSet();
        int maxResult = 0;
        char[] charList = s.toCharArray();
        while(R<charList.length){//R是index
            while(set.contains(charList[R])){
                set.remove(charList[L++]);
                mx--;
            }
            set.add(charList[R++]);
            maxResult = Math.max(maxResult,++mx);
        }
        return maxResult;
    }
}

等差数列划分

在这里插入图片描述
这里提供两种解法,一种是我想到的双指针写法,这个写法是我在看了滑动窗口以后思考到的,但是有点取巧的意思,里面把等差数列的值取出来了,将问题转化为:局部最长子串有多少个,每个有多长的问题

//双指针写法
class Solution {
    public int numberOfArithmeticSlices(int[] nums) {
        int n = nums.length;
        if(n<3){
            return 0;
        }
        int R = 2;
        int L = 0;
        int maxLen = 2;
        int result = 0;
        while(R<nums.length){
            if(nums[R]-nums[R-1] != nums[R-1] - nums[R-2]){
                //不是等差数列了
                int lastR = R-1;
                maxLen = Math.max(2,(lastR-L)+1);
                L = lastR;
                result+=getVal(maxLen);
            }
            R++;
        }
        //最后退出时,需要重新结算
        maxLen = Math.max(2,(R-L));//这里加1减1抵消,因为出来的时候R多了一个
        result+=getVal(maxLen);
        return result;
    }
    int getVal(int len){
        if(len == 2){
            return 0;
        }
        int num = 1;
        for(int i = 0;i<len-3;i++){
            int acc = i+2;
            num+=acc;
        }
        return num;
    }
}

这道题也可以使用DP求解,但是这个dp条件有点怪
先附上leetcode中dp的相关描述
在这里插入图片描述
我的问题是,这个dp这里说的是nums[i]结尾长度大于等于3的等差数列个数,然而实际上,dp[i]并不是这个数,举例子,1,2,3,4,5 dp[4]的值是3,但其实5结尾的大于等于3的等差数列个数并不是3,而是dp1-dp5的和

//dp
class Solution {
    public int numberOfArithmeticSlices(int[] nums) {
        int len = nums.length;
        if (len < 3) {
            return 0;
        }
        // dp[i] 表示以:nums[i] 结尾的、且长度大于等于 3 的连续等差数列的个数
        int[] dp = new int[len];
        int res = 0;
        // 从下标 2 开始,才有可能构成长度至少大于等于 3 的等差数列
        for (int i = 2; i < len; i++) {
            if (nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]) {
                dp[i] = dp[i - 1] + 1;
                res += dp[i];
            }
        }
        return res;
    }
}

2、操作系统 第五章剩余内容

线程调度

在支持线程的操作系统上,内核线程是操作系统调度的,用户线程是由线程库调度的

竞争范围

用户线程和内核线程有一个区别在于他们的调度方式不同
对于实现多对一和多对多模型的系统线程库会调度用户级线程,让其可以在LWP上运行。这种方案叫进程竞争范围(PCS System-Contention Scope),因为他是在一个进程的不同线程之间的。
内核采用系统竞争范围(System-Contention Scope)。采用SCS调度发生在系统所有线程之间,采用一对一模型的系统,只采用SCS调度。

使用Pthreads调度 代码API查看

在这里插入图片描述

多处理器调度

调度方式

有两种方式

  1. 非对称多处理:一个处理器处理所有调度/IO,等系统活动,其他处理器只执行用户代码,这种代码简单,因为他简化了数据的共享
  2. 对称多处理(SMP):每个处理器有他自己的调度 必须确保他们不会选择同样的进程
处理器亲和性

由于将一个进程移动到其他处理器中时,对系统内存的消耗代价较大(旧进程需要清除,新进程需要备份),所以大部分的操作系统中进程都会运行在同一个处理器上,这种依赖就是处理器亲和性。

  • 软亲和性 一个系统试图让进程运行在统一处理器上(不保证它一定会)
  • 硬亲和性 必须在制定的处理器运行

系统的内存架构可能会影响处理器的亲和性

负载平衡

对于SMP而已比较重要,需要保证每个CPU都在忙碌中。以防止一个或多个处理器空闲,其他的处理器高负载的情况。对于有公共队列的操作系统,并不太需要负载平衡。因为当队列中有进程,就会及时的被处理器处理。
常用的两种方法:

  • 推迁移 定时任务检查每个处理器的负载,如发现不平衡,则将高负载处理器中的进程push到空闲进程
  • 拉迁移 与推迁移的from to 不同 从空闲进程pull

这两种任务通常并行执行,不相互排斥

负载平衡会破坏亲和性(会出现线程转移的情况)

多核处理器

将多个处理器放置在同一个物理芯片上,从而产生多核处理器
多核处理器的SMP比单核处理器的SMP更快,功耗更低
多核处理器的调度问题复杂,访问内存时会消耗大量时间。针对这种问题,现在很多硬件设计都采用了多线程的处理器核,每个核会分配到两个(或多个)物理线程。这样的话,当一个线程(这里的线程不是物理线程!)需要等待时,CPU切换到另外一个物理线程。
处理器核的多线程有两种:

  • 粗粒度 当发生长时间等待的事件时切换
  • 细粒度 在更细的粒度级别(通常在指令周期边界上)上切换线程

实时CPU调度

主要是一些对时效性要求高的软件需要(汽车系统等)

最小化延迟

这类系统考虑实时系统的事件驱动特性,通常这种系统等待一个实时事件的发生。这种事件发生到服务的这段时间称为事件延迟
有两种延迟会影响实时系统的性能:

  • 中断延迟 从CPU收到中断到中断处理程序开始的时间(尽可能减少)
  • 调度延迟 停止一个进程到启动另一个进程的时间 操作系统应该最大限度的减少这种延迟。这种延迟降低的有效技术是提供抢占式内核
优先级调度

实时操作系统的调度支持抢占的优先权算法,这种算法仅可以提供软实时功能,不能提供硬实时,需要附加调度特征,同时,这种调度具有的特点:周期性,需要根据周期性来增加调度的特征
截至期限:周期到的时候的时间

单调速率调度

抢占,静态优先级。要求进程是周期的
周期越短,优先级越高,周期越长,优先级越低。
单调速率调度可以被认为是最优的
调度N个进程的最坏情况CPU利用率为:N(2^(1/N)-1)

最早截至期优先调度(EDF)

根据截止期限动态分配优先级,截止时间越早,优先级越高,截止时间越晚,优先级越低
EDF调度不要求进程是周期的,也不要求CPU执行长度固定,只要求在可行时需要宣布他的截止日期。

比例分享调度

调度程序在所有应用之间分配T股,如果一个应用程序接收N股,则有N/T的总处理时间
准入控制策略:当请求股数小于总股数才可以进入

操作系统案例

这里只讲Linux和Windows 还有Solaris系统 建议在书中观看

Linux

默认调度算法:完全公平调度程序(CFS)
Linux的调度基于调度类,每一个类有特定优先级,不同内核针对不同的调度类。
CFS调度按比例给每个任务分配一定比例的CPU处理时间。每个任务的比例是根据他自身的友好值来计算的。这个值增加时,将会降低该任务的优先级,而因为降低了优先级,所以对其他的任务友好。CFS没有使用离散的时间片,而是目标延迟的方式让每个任务执行他应该执行的时间。
这个算法执行并不按照优先级,而是按照vruntime来维护虚拟运行时间,举个例子,如果一个任务默认优先级,需要200ms,那么他在更低优先级,他的vruntime大于200ms,在更高优先级,他的vruntime小于200ms,这个时间基于任务优先级的衰减因子。(具体在书中P160页查看)

在这里插入图片描述

Windows

Windows采用基于优先级的,抢占调度算法来调度线程。这里主要想说Windows的用户模式调度(UMS)
因为Windows用户交互较多,系统需要提供比较好的表现
当一个进程移动到前台,windows增加他的时间片,通常是原来的三倍,这个增加给前台进程3倍的时间来运行(在被抢占前)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值