20170702Windows10_07_线程优先级及CPU亲和度

线程:

1:线程是Windows里面的一个精髓,Windows是操作系统更简单,有很多窗口,容易交互,Windows将所有窗口资源划分在了线程里面,因为多线程的存在支持了界面,窗口资源属于线程的。
2:线程用到C语言的一切全局变量,是线程不安全的,n个线程同时访问一个变量,可能会出错,这就是线程不安全,原子操作可以保证不管是多少条线程,当前的作用就是作用在资源之上的,不会被其他线程打断。很多时候,原子操作都是不能解决根本问题的,需要上锁(上锁就是锁一长段代码)。
3:除了旋转锁,还会有其他锁。旋转锁在单核里面,有两个优先级比较高的线程使用了旋转锁,可能导致其他线程无法被运行,这涉及到线程优先级。

线程的优先级:

1:系统线程调度去里面的线程就有被分配时间片的可能性,否则就不能分配时间片,不可调度的线程包括阻塞下来的线程(GetMessage,WaitForSingleObject等)。线程阻塞是操作系统知道他需要等待,不需要调度,才把他放到一边去。
2: SuspendThread只是将线程暂停,与不可调度是两回事,SuspendThread只会将线程挂起,将暂停计数+1,从而使得其与调度区分开。从而实现挂起
3:并非所有的可调度区的线程都是按照顺序来调度的,而是有一个优先级,每个线程肯定都有自己的优先级,普通的线程优先级为8。
4: SetProcessAffinityMask()可以设置进程在单核运行。
5:CPU正在执行优先级低的线程,此时,当处于不可调度区哟县级高的线程突然变为可调度的时候,他就会抢占时间片,CPU会停止当前低优先级线程的执行,转而执行优先级高的线程,高优先级的线程可以打断低优先级线程的执行。优先级越低就只能在CPU越空闲的时候来执行,0优先级的线程在操作系统中有且只有一个,称之为页面清零线程。当所有的线程都变为不可调度的时候,就会执行这个唯一的0号线程。
6:自己的线程不可以设置优先级到0。低优先级可以帮我们做很多事情,例如做一些回收的操作,部分写文件的操作,只需要在系统比较空闲的时候来做即可,把这些操作放在低优先级的线程中,就可以让其在系统相对比较空闲的时候来处理。
7:现成的优先级为0到31之间,如下图所示:

    线程的优先级会受到进程的优先级的影响,进程实际上是不存在执行的(只是空间),但是会有进程优先级。现成的优先级是根据进程的优先级来决定的,并不是0到31想设置哪个就设置哪个。不能直接设置为数值,在CreateProcess的时候,会有一个宏可以指定优先级。
    注意:永远不要把进程的优先级设置到实时(real-time),否则他将有最高的打断权限,这个进程可能会打断操作系统的一些执行,当打断这些的时候,整个操作系统使用起来会非常卡顿,进程里面有写的不好的还可能导致整个Windows的速度变慢。也是因为这个,XP系统下很多时候关闭程序需要较长时间。进程的权限默认为正常的。
8:real-time是必须要管理员权限才能够来做的,xp之后就需要申请权限才行,现在写real-time程序的非常少。通常,我们最多将自己的进程设置到above-normal就可以了,设置到high就会非常高了。
9:线程也会设置自己的优先级,六个级别都可以来设置,线程优先级和进程优先级相结合就知道其线程优先级的级号了。 可以发现,0~31之间的部分级号是没有的(17~21)这些优先级是给操作系统里面的一些IO操作来使用的、和硬件相关的,都给到了Windows的内核的。这样可以确保正常情况下,系统一定会优先响应硬件操作。
10:在任务管理器里面,我们可以手动设置进程为不同的优先级,这个设置会影响到进程里面线程的实际优先级。 我们也可以使用SetPriorityClass()函数来设置当前进程的优先级,也可以设置其他进程的优先级。
11: 线程优先级的设定可以由SetThreadPriority()函数来设置,但是,设置现成的优先级的话,就不能设置线程立即启动,需要传递CREATE_SUSPENDED,然后设置线程的优先级,最后才让线程开始执行。即,启动的时候先挂起,设置优先级后在使之运行。优先级低并不一定能够降低他的运行次数。在单核下,多个高优先级和一个低优先级,低优先级的线程就可能会饿死,长时间得不到执行。
12:在单核下面,当一个饥饿线程超过2秒的时候,操作系统会自动提升他的优先级,执行后,再降低他的优先级。但是多核处理器,会有所不同。当系统自动进行线程优先级的提升的时候,会打断自己的一些调度,可以通过SetThreadPriorityBoost(),参数传递TRUE为关闭系统的自动提升优先级,FALSE为打开系统的自动提升。
13:CPU高速缓存器是为了让CPU很快的读取内存中的数据,CPU读取内存里面的数据后,会将后面的一些关联的东西也读取到告诉缓存区里面,CPU在告诉缓存器里面读数据的速度和读取寄存器的速度相当。内存的读取速度远低于CPU的执行速度。
14:在多线程编程中,如果涉及到多个线程使用一个数据,需要数据的同步,最好是让这几个线程在同一个CPU里面执行。 与进程相同,所设置线程在一个CPU核里面执行,可以使用SetThreadAffinityMask()。可以将三个线程分别设置在三个内核里面,就可以让他们三个线程各运行各的。基本可以保证他们都会被运行到。
15:这些都是在一些特殊的编程中会遇到。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值