线程优先级
优先级倒置问题
6.3.1 优先级倒置很多实时系统都实现了线程优先级机制,每个线程被分配一个优先级,优先级高的线程只要具备了运行的条件,或者说进入了就绪态,就可以立即执行。
除了优先级最高的那个线程外,其他线程在执行过程中随时都可能停下来,让给优先级更高的线程先执行。
抢占式调度策略能保证系统的实时性。
由于多个线程共享资源,在采用基于优先级调度策略时会出现较低优先级的线程先于高优先级线程执行的情况,即优先级倒置(priority inversion)问题。
优先级倒置可能使实时性要求高的线程错过临界期限(critical deadline),从而导致系统崩溃。
在采用基于优先级的调度策略,一旦两个线程共享了资源,那么其中之一通常具有较高的优先级。
高优先级的线程期望一旦准备就绪就能运行,但当高优先级线程就绪,而低优先级线程正在使用共享资源时,高优先级线程必须等待,直到低优先级线程完成对共享资源的操作。
这时,我们称高优先级线程被挂起。
当高优先级线程挂起时,中优先级的线程抢先了正在使用共享资源的低优先级线程,此时高优先级线程已准备就绪并等待运行,但中优先级线程此刻正在运行,这时就出现了优先级倒置问题。
下图以三个不同优先级的线程为例描述一个优先级倒置的示例。
高优先级线程H 和低优先级线程L 要共享资源R,为了保证数据的完整性,它们需要通过信号量S 来保证对临界资源的互斥访问。
线程M 的优先级介于H 和L 之间。
图6.1 一个优先级倒置的示例(1)低优先级线程L 取得信号量S 的所有权,即做了P 操作,但还没有做V 操作。
(2)线程H 的优先级高于线程L,操作系统内核通过调度程序,将线程L 切换出去,将线程H 置为运行态。
(3)线程H 执行到中途需要访问共享资源R,必须先对信号量S 做P 操作。
因为此信号量目前还没有恢复,于是线程H 阻塞在信号量S 上。
(4)线程L 重新被切换到运行态。
(5)此时线程M 进入到就绪态,因为线程M 的优先级高于任务L,于是内核进行线程切换,将线程M 置为运行态。
JAVA多线程的使用场景与注意事项总结
JAVA多线程的使用场景与注意事项总结Java多线程是指在一个程序中同时运行多个线程,每个线程都有自己的执行代码,但是又共享同一片内存空间和其他系统资源。
多线程的使用场景和注意事项是我们在开发中需要关注的重点,下面将详细进行总结。
一、Java多线程的使用场景:1.提高程序的执行效率:多线程可以充分利用系统资源,将一些耗时的操作放到一个线程中执行,避免阻塞主线程,提高程序的执行效率。
2.实现并行计算:多线程可以将任务拆分成多个子任务,每个子任务分配给一个线程来执行,从而实现并行计算,提高计算速度。
3.响应性能提升:多线程可以提高程序的响应性能,比如在用户界面的开发中,可以使用多线程来处理用户的输入和操作,保证界面的流畅性和及时响应。
4.实时性要求高:多线程可以实现实时性要求高的任务,比如监控系统、实时数据处理等。
5.任务调度与资源管理:多线程可以实现任务的调度和资源的管理,通过线程池可以更好地掌控任务的执行情况和使用系统资源。
二、Java多线程的注意事项:1.线程安全性:多线程操作共享资源时,要注意线程安全问题。
可以通过使用锁、同步方法、同步块等方式来解决线程安全问题。
2.死锁:多线程中存在死锁问题,即多个线程相互等待对方释放资源,导致程序无法继续执行。
要避免死锁问题,应尽量减少同步块的嵌套和锁的使用。
3.内存泄漏:多线程中存在内存泄漏问题,即线程结束后,线程的资源没有得到释放,导致内存占用过高。
要避免内存泄漏问题,应及时释放线程资源。
4.上下文切换:多线程的切换会带来上下文切换的开销,影响程序的执行效率。
要注意合理分配线程的数量,避免过多线程的切换。
5. 线程同步与通信:多线程之间需要进行同步和通信,以保证线程之间的正确协调和数据的一致性。
可以使用synchronized关键字、wait(和notify(方法等方式进行线程同步和通信。
6.线程池的使用:在多线程编程中,可以使用线程池来管理线程的创建和销毁,可以减少线程的创建和销毁的开销,提高程序的性能。
io密集型线程池参数配置
io密集型线程池参数配置
io密集型线程池是一种针对I/O密集型任务的线程池,它专门为那些涉及大量的I/O操作的应用程序进行优化。
在使用io密集型线程池时,需要合理地配置相关参数以确保线程池的效率和性能。
以下是一些常见的io密集型线程池参数配置:
1. 线程池大小:线程池大小指的是线程池中线程的数量。
对于io密集型任务,线程数应该设置为尽可能多的数量,以确保能够利用系统资源最大化地执行I/O操作。
2. 队列容量:队列容量指的是线程池中任务队列的大小。
对于io密集型任务,队列容量应该设置为较大的值,以便缓解I/O操作的压力,并确保任务能够得到及时处理。
3. 空闲时间:空闲时间指的是线程在没有任务可执行时保持空闲的时间。
对于io密集型任务,空闲时间应该设置为较短的值,以便能够尽快地处理新的I/O操作。
4. 线程优先级:线程优先级指的是线程在执行任务时的优先级。
对于io密集型任务,线程优先级应该设置为较低的值,以便避免过多的CPU占用,从而保证I/O操作的顺利进行。
5. 饱和策略:饱和策略指的是当线程池中的线程都在忙碌时,新的任务应该如何处理。
对于io密集型任务,建议采用CallerRunsPolicy策略,即将任务交给调用线程来执行,以避免因线程池饱和而导致的任务阻塞。
通过合理地配置上述参数,可以有效地提高io密集型线程池的
效率和性能,从而更好地满足应用程序对I/O操作的需求。
Linux线程的状态与调度
Linux线程的状态与调度1,线程的⽣命周期线程从创建、运⾏到结束总是处于下⾯五个状态之⼀:新建状态、就绪状态、运⾏状态、阻塞状态及死亡状态。
1.新建状态(New):当⽤new操作符创建⼀个线程时,例如new Thread(r),线程还没有开始运⾏,此时线程处在新建状态。
当⼀个线程处于新⽣状态时,程序还没有开始运⾏线程中的代码2.就绪状态(Runnable)⼀个新创建的线程并不⾃动开始运⾏,要执⾏线程,必须调⽤线程的start()⽅法。
当线程对象调⽤start()⽅法即启动了线程,start()⽅法创建线程运⾏的系统资源,并调度线程运⾏run()⽅法。
当start()⽅法返回后,线程就处于就绪状态。
处于就绪状态的线程并不⼀定⽴即运⾏run()⽅法,线程还必须同其他线程竞争CPU时间,只有获得CPU时间才可以运⾏线程。
因为在单CPU的计算机系统中,不可能同时运⾏多个线程,⼀个时刻仅有⼀个线程处于运⾏状态。
因此此时可能有多个线程处于就绪状态。
对多个处于就绪状态的线程是由Java运⾏时系统的线程调度程序(thread scheduler)来调度的。
3.运⾏状态(Running)当线程获得CPU时间后,它才进⼊运⾏状态,真正开始执⾏run()⽅法.4. 阻塞状态(Blocked)线程运⾏过程中,可能由于各种原因进⼊阻塞状态:1>线程通过调⽤sleep⽅法进⼊睡眠状态;2>线程调⽤⼀个在I/O上被阻塞的操作,即该操作在输⼊输出操作完成之前不会返回到它的调⽤者;3>线程试图得到⼀个锁,⽽该锁正被其他线程持有;4>线程在等待某个触发条件;......所谓阻塞状态是正在运⾏的线程没有运⾏结束,暂时让出CPU,这时其他处于就绪状态的线程就可以获得CPU时间,进⼊运⾏状态。
5. 死亡状态(Dead)有两个原因会导致线程死亡:1) run⽅法正常退出⽽⾃然死亡,2) ⼀个未捕获的异常终⽌了run⽅法⽽使线程猝死。
java程序某个线程未执行的原因
一、简介Java作为一种常用的编程语言,其多线程的特性使得程序能够同时执行多个任务,提高了程序的执行效率。
然而,在实际开发中,经常会遇到某个线程未执行的情况,这给程序的稳定性和性能带来了一定的影响。
本文将分析Java程序中某个线程未执行的原因,并提出相应的解决方案。
二、线程未执行的原因1. 线程阻塞当线程被阻塞时,无法执行其所包含的代码,导致线程未执行。
线程被阻塞的原因可能有:a) 等待输入/输出操作完成b) 等待获取锁c) 等待其他线程的执行结果2. 线程优先级线程的优先级较低时,可能会被其他优先级较高的线程抢占资源,造成线程未执行。
3. 异常情况当线程执行过程中发生异常,例如空指针异常、数组越界异常等,导致线程未执行。
4. 线程调度系统的线程调度机制可能导致某个线程未得到执行的机会,例如抢占式调度规则等。
5. CPU资源不足当CPU资源不足时,系统会根据一定的调度规则分配CPU资源给各个线程,可能导致某个线程未得到执行的机会。
三、解决方案针对上述线程未执行的原因,可以采取以下解决方案:1. 优化代码逻辑和算法,减少线程的阻塞时间,提高程序的执行效率。
2. 合理设置线程的优先级,确保重要的线程能够优先得到执行,避免线程被抢占资源。
3. 使用try-catch语句捕获线程执行过程中的异常,防止异常导致线程未执行的情况。
4. 考虑线程调度的机制,合理安排线程的执行顺序,避免某个线程因调度而未得到执行。
5. 确保系统有足够的CPU资源,避免因资源不足导致线程未执行的情况。
四、总结Java程序中某个线程未执行的原因可能很多,需要在编程和系统调度等方面多方面考虑,才能有效地解决此类问题。
通过优化代码、合理设置线程优先级、捕获异常等手段,可以有效地避免线程未执行的情况,提高程序的稳定性和性能。
因为Java程序复杂性的原因,程序中某个线程未执行可能是由于多种原因导致的,解决这一问题需要程序员有深厚的技术功底。
Java程序设计任务驱动式教程 任务二十八 线程的生命周期与优先级(线程的状态与调度)
28.4 必备知识
4. 阻塞状态(Block) 由于某种原因使得运行中的线程不能继续执行,该线程进行阻塞态。此时 线程不会被分配CPU时间,无法执行。Java中提供了大量的方法来阻 塞线程。下面简单介绍几个。 sleep() 方法:指定在指定的时间内处于阻塞状态。指定的时间一过, 线程进入可执行状态。 Wait()方法: 使得线程进行阻塞状态。它有两种格式:一种是允许指 定以毫秒为单位的一段时间内作为参数。该格式可以用notify()方法被 调用或超出指定时间时,线程可重新进入可运行状态。另一种格式没 有格式,该格式必须是notify()方法被调用后才能使线程进行可运行状 态。 5.死亡状态(Dead) 正常情况下,当线运行结束后进入死亡状态。有两种情况导致线程进 入死亡状态:自然撤销或被停止。当运行run()方法结束时,该线程就 自动自然撤销,当一个应用程序因故停止运行时,系统将终止该程序 正在执行的所有线程。当然也可以调用stop()方法来终止线程。但一 般不推荐使用,因为会产生异常情况。
第1章目录
7/19
28.2 实现方案
问题分析 本任务是创建一个Java多线程状态设置与线程调度应用程序,首先创建一个 普通类EatApple,在此类中创建两个方法。第一个方法为put()方法,实 现将苹果放入到盘子中。第二个方法为get()方法,实现将从盘子中取苹 果。然后再创建两个线程来分别调用put()方法和get()方法来完成苹果的 取放操作。 解决步骤 1.打开Eclipse,在study项目中创建包com.task28,再确定类名EatApple。得到 类的框架。 2.在public class EatApple{下面一行输入类的属性描述:
12/19 12/
28.3 代码分析
线程上下文切换的方式
线程上下文切换的方式全文共四篇示例,供读者参考第一篇示例:线程上下文切换指的是在多线程并发执行时,CPU需要在不同的线程之间进行切换以保证多个线程能够得到合理的执行。
线程上下文切换是一种非常重要的操作,因为它决定了系统的性能和效率。
线程上下文切换的方式有很多种,下面我们来逐一介绍。
一、抢占式调度抢占式调度是一种常见的线程调度方式,也叫做时间片轮转法。
在抢占式调度中,每个线程被分配一个固定长度的时间片,当时间片用完时,操作系统会暂停当前线程的执行,并切换到下一个线程。
这种方式能够保证每个线程都能得到公平的执行机会,避免某个线程一直占用CPU而导致其他线程无法执行的情况。
二、协同式调度三、优先级调度优先级调度是一种常见的线程调度方式,通过设置不同线程的优先级来实现线程的调度。
在优先级调度中,CPU会选择优先级最高的线程来执行,当同一优先级的线程有多个时,采用抢占式调度的方式。
优先级调度能够根据线程的重要性和紧急程度来合理分配CPU资源,但是如果优先级设置不合理或者出现优先级反转的情况,可能会导致系统性能下降。
四、时间片调度分时调度是一种常见的线程调度方式,在分时调度中,多个线程共享CPU资源,系统会根据一定的策略来分配CPU时间片给每个线程。
分时调度能够保证每个线程都有机会执行,但是由于多个线程共享CPU资源,可能会导致上下文切换频繁,影响系统的性能和效率。
总结来看,线程上下文切换是多线程编程中的一个重要问题,不同的上下文切换方式有着各自的特点和适用场景。
在实际应用中,需要根据具体的情况选择合适的上下文切换方式,以保证系统的性能和效率。
希望通过本文的介绍,读者能够更深入了解线程上下文切换的方式,为多线程编程提供更好的指导。
第二篇示例:线程上下文切换是计算机系统中一个非常重要的概念,它指的是在多线程环境下,系统从一个线程切换到另一个线程时,需要保存当前线程的上下文信息,并恢复下一个线程的上下文信息。
线程的上下文信息包括寄存器状态、栈指针、程序计数器等。
谁是第一?线程的优先级和调度
谁是第一?线程的优先级和调度
惠毓明
【期刊名称】《软件世界》
【年(卷),期】1995(000)009
【摘要】OS/2应用超过其它应用的最大优点之一是具有多线程能力。
不仅仅是OS/2多任务应用(它作为一个或多个可执行单元)可在单处理机中以抢先方式快速开关,同时在应用内部还可设计若干线程,这样,这些线程彼此之间和系统的其它部分就可以最大限度地使用处理机并使这些应用获得最大的吞吐力。
尽管线程的概念是很直观的,很多人能理解它,却在实现、使用和处理它们时仍然有困难。
将实实在在地考察它们在系统中是如何处理的,如何定义的优先数和它们如何实现同步。
同样也要考察一下它们在多处理机系统中的含义。
【总页数】3页(P53-55)
【作者】惠毓明
【作者单位】无
【正文语种】中文
【中图分类】TP316
【相关文献】
1.多核同时多线程处理器的线程调度器设计 [J], 周佳佳;李涛;黄小康
2.读者优先级调度和写者优先级调度算法的改进 [J], 江波
3.Java多线程编程中线程生存期和优先级的探讨 [J], 蒋峰
4.基于线程调度顺序控制的多线程程序测试 [J], 李婧
5.优先级有限时的单处理器静态优先级调度 [J], 王保进;李明树;王志刚
因版权原因,仅展示原文概要,查看原文内容请购买。
简析Windows系统的调度机制_2015011224
电子系 无51班 赵少靖 学号:**********
Windows系统的调度的粒度为线程,首先Windows为每一个线程分配调度优先级。调度根据优先级采用抢占式的调度策略,具有最高优先级的总是最先被执行。每一个线程都分配了一定的时间片,系统通过改变线程的状态来进行线程调度。
Windows系统使用32个优先级来表示线程要求执行的紧迫性,优先级用0~ 31的数字来表示。其中0优先级为内存页清零线程保留,1~ 15为可变优先级,16~ 31为实时优先级别。在应用创建线程时用户可以用形象的优先级描述来设置优先级,当创建进程时可以,可以赋予实时、高、高于一般、一般、低于一般和空闲的优先级别,当创建线程时可以在进程优先级的基础上进一步赋予尽量实时、最高、高于一般、一般、低于一般、最低和空闲的优先级别。处理器调度时参考两个优先级设置,一个是从当前线程所在进程的基准优先级,另一个是线程的优先级。一般来说,应用线程运行在可变优先级别1~ 15范围内,如果需要进入实时优先级别16~ 31范围内来运行,必须取得更高的调度优先级特权。Windows操作系统只有一个内存页清零线程具有最低的调度优先级级别0,以便系统利用空闲时间对内存页清零。
系统中同时有多个线程存在,而处理器一次只能运行一个线程。Windows通过调度数据库来为每一个优先级的线程维护一个就绪等待队列,当处理器需要调入一个线程运行的时候,系统会从调度数据库中找到一个具有最高优先级的就绪线程,并给它分配时间。如果等待队列中有线程比正在运行的线程优先级高,运行的线程就会保存它的上下文环境并进入就绪队列,高优先级的线程恢复它的上下文环境,并进入运行状态。当一个线程进入运行状态时,它就获得了一个可以运行的时间配额。时间配额用完后,调度器会查找调度数据库看是否有就绪的线程在等待,如果有就会将等待的线程运行,而将当前的线程转入等待或者就绪态,如果没有则再分配一个时间片给这个线程。
进程优先级与线程优先级
进程优先级与线程优先级学习各种高级外挂制作技术,马上去百度搜索"魔鬼作坊",点击第一个站进入,快速成为做挂达人。
SetThreadPriority与SetPriorityClass区别知识点:线程优先级获取当前线程句柄线程优先级设置线程优先级变动线程优先级获取线程优先级(Thread priority)简单的说就是(线程)的优先级越高,那么就可以分占相对多的CPU时间片。
每个进程都有相应的优先级,优先级决定它何时运行和占用CPU时间。
最终的优先级共分32级,是从0到31的数值,称为基本优先级别。
进程优先级priority class标志优先级值idle(低)IDLE_PRIORITY_CLASS4Below低于标准BELOW_NORMAL_PRIORITY_CLASS此值在2000以下系统不支持normal(标准)NORMAL_PRIORITY_CLASS9(前台)或7(后台) Above高于标准ABOVE_NORMAL_PRIORITY_CLASS此值在2000以下系统不支持high(高)HIGH_PRIORITY_CLASS13realtime(实时)REALTIME_PRIORITY_CLASS24一个线程创建的时候,会继承进程的优先级等级。
另外线程优先级可以用SetThreadPriority 来进行微调:线程优先级等级标志优先级值1idle(最低)THREAD_PRIORITY_IDLE如果进程优先级为realtime则调整为16,其它情况为12LOWEST低THREAD_PRIORITY_LOWEST-2(在原有基础上-2)3BELOW低于标准THREAD_PRIORITY_BELOW_NORMAL -1(在原有基础上-1)4NORMAL(标准)THREAD_PRIORITY_NORMAL不变(取进程优先级值)5ABOVE高于标准THREAD_PRIORITY_ABOVE_NORMAL+1(在原有基础上+1)6HIGHEST(高)THREAD_PRIORITY_HIGHEST+2(在原有基础上+2)7CRITICAL(最高)THREAD_PRIORITY_TIME_CRITICAL如果进程优先级为realtime则调整为31,其它情况为15二、获取当前线程句柄HANDLE GetCurrentThread(VOID)//返回当前进句柄DWORD GetCurrentThreadId(VOID)//返回当前进程ID值1、其它线程函数BOOL SetThreadPriority设置一个线程的优先级别int GetThreadPriority返回一个线程的优先级别SetThreadPriorityBoost设置线程是否禁用动态调整优先级功能。
c语言task 用法 -回复
c语言task 用法-回复标题:C语言Task用法详解:实现高效编程的利器引言:C语言作为一种高效、强大的编程语言,经常被用于开发底层应用,系统软件以及嵌入式系统。
其灵活性和效率使其成为广大开发者的首选。
而在C语言中,Task(任务)是管理和执行并发操作的重要工具。
本文将详细介绍C语言Task的用法,帮助读者深入了解并充分利用这一强大功能。
一、任务的概念与创建任务(Task)是指在多核或单核环境中,能够并发执行的代码片段。
在C语言中,任务可以通过创建线程或进程的方式实现。
在这两种方式中,线程更为常用和广泛,因此本文将主要关注于线程的概念和创建。
要创建一个线程,可以使用C语言提供的pthread库。
以下为创建一个线程的基本步骤:1. 引入pthread库的头文件:c#include <pthread.h>2. 定义线程函数:线程函数是需要并发执行的代码,可以定义为如下格式:cvoid* function_name(void* arg);3. 创建线程:在主函数中使用pthread_create函数来创建线程,创建时需要传入线程的标识符、线程属性和线程函数,具体如下:cint pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine)(void*), void* arg);二、任务的同步与互斥在多任务并发执行时,往往存在共享数据的访问问题。
为了保证数据的正确性和一致性,需要采用同步和互斥的机制。
C语言通过信号量、互斥锁和条件变量等机制来实现任务的同步与互斥。
1. 信号量(Semaphore):信号量是用来控制多个任务对共享资源的访问的一种机制。
C语言通过sem_init、sem_wait和sem_post等函数来实现信号量的创建、等待和释放。
2. 互斥锁(Mutex):互斥锁是一种保护共享资源的机制,保证同一时间只能有一个任务对资源进行操作。
linux线程优先级取值范围
linux线程优先级取值范围
在Linux系统中,线程优先级的取值范围是0~99,其中数值越大表示优先级越高。
然而,这只代表了部分情况。
实际上,线程优先级的取值范围和具体的系统实现有关。
在Linux中,线程的优先级由nice值和系统默认优先级共同决定。
系统默认优先级为120,nice值的取值范围为-20~19。
因此,通过计算公式线程数值 = 系统默认优先级+ nice值,可以得出线程的最小优先级为100,最大优先级为139。
然而,如果考虑实时进程和非实时进程,Linux进程实际上实现了140个优先级范围,取值范围是从 [0, 139]。
其中,实时进程的优先级范围是[0, 99],而非实时进程的优先级范围是[100, 139]。
所以,线程优先级的取值范围还要考虑到实时进程和非实时进程的差别。
请注意,具体的取值范围可能因Linux内核版本和系统配置而有所不同。
如需了解更多关于Linux线程优先级的取
值范围的信息,建议查阅相关的技术手册或咨询专业的技术人员。
简述线程,程序、进程的基本概念。以及他们之间关系是什么?
简述线程,程序、进程的基本概念。
以及他们之间关系是什么?1. 简述线程,程序、进程的基本概念。
以及他们之间关系是什么?线程与进程相似,但线程是⼀个⽐进程更⼩的执⾏单位。
⼀个进程在其执⾏的过程中可以产⽣多个线程。
与进程不同的是同类的多个线程共享同⼀块内存空间和⼀组系统资源,所以系统在产⽣⼀个线程,或是在各个线程之间作切换⼯作时,负担要⽐进程⼩得多,也正因为如此,线程也被称为轻量级进程。
程序是含有指令和数据的⽂件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。
进程是程序的⼀次执⾏过程,是系统运⾏程序的基本单位,因此进程是动态的。
系统运⾏⼀个程序即是⼀个进程从创建,运⾏到消亡的过程。
简单来说,⼀个进程就是⼀个执⾏中的程序,它在计算机中⼀个指令接着⼀个指令地执⾏着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,⽂件,⽂件,输⼊输出设备的使⽤权等等。
换句话说,当程序在执⾏时,将会被操作系统载⼊内存中。
线程是进程划分成的更⼩的运⾏单位。
线程和进程最⼤的不同在于基本上各进程是独⽴的,⽽各线程则不⼀定,因为同⼀进程中的线程极有可能会相互影响。
从另⼀⾓度来说,进程属于操作系统的范畴,主要是同⼀段时间内,可以同时执⾏⼀个以上的程序,⽽线程则是在同⼀程序内⼏乎同时执⾏⼀个以上的程序段。
线程上下⽂的切换⽐进程上下⽂切换要快很多进程切换时,涉及到当前进程的CPU环境的保存和新被调度运⾏进程的CPU环境的设置。
线程切换仅需要保存和设置少量的寄存器内容,不涉及存储管理⽅⾯的操作。
2. 线程有哪些基本状态?这些状态是如何定义的?1. 新建(new):新创建了⼀个线程对象。
2. 可运⾏(runnable):线程对象创建后,其他线程(⽐如main线程)调⽤了该对象的start()⽅法。
该状态的线程位于可运⾏线程池中,等待被线程调度选中,获取cpu的使⽤权。
3. 运⾏(running):可运⾏状态(runnable)的线程获得了cpu时间⽚(timeslice),执⾏程序代码。
细说C#多线程那些事-线程同步和多线程优先级
细说C#多线程那些事-线程同步和多线程优先级上个⽂章分享了⼀些多线程的⼀些基础的知识,今天我们继续学习。
⼀、Task类上次我们说了线程池,线程池的QueueUserWorkItem()⽅法发起⼀次异步的线程执⾏很简单但是该⽅法最⼤的问题是没有⼀个内建的机制让你知道操作什么时候完成,有没有⼀个内建的机制在操作完成后获得⼀个返回值。
为此,可以使⽤System.Threading.Tasks中的Task类。
Task类在命名空间System.Threading.Tasks下,通过Task的Factory返回TaskFactory类,以TaskFactory.StartNew(Action)⽅法可以创建⼀个新的异步线程,所创建的线程默认为后台线程,不会影响前台UI窗⼝的运⾏。
如果要取消线程,可以利⽤CancellationTakenSource对象。
如果要在取消任务后执⾏⼀个回调⽅法,则可以使⽤Task的()⽅法。
简单代码实现:using System;using System.Threading.Tasks;namespace Threading{class Program{public static Int32 ThreadSum(Int32 n){Int32 sum = 0;for (; n > 0; --n)sum += n;return sum;}static void Main(string[] args){var t = new Task<Int32>(n => ThreadSum((Int32)n), 100);t.Start();var cwt = t.ContinueWith(task => Console.WriteLine("The result is {0}", t.Result));Console.ReadKey();}}}Task类⽰例代码using System;using System.Threading.Tasks;public class Example{public static void Main(){Task t = Task.Factory.StartNew( () => {int ctr = 0;for (ctr = 0; ctr <= 1000000; ctr++){}Console.WriteLine("Finished {0} loop iterations",ctr);} );t.Wait();}}更多内容参考:⼆、异步执⾏委托的异步执⾏代码:BeginInvoke() 和 EndInvoke()using System;namespace Threading{public delegate string MyDelegate(object data);class Program{public static string Thread1(object data){return data.ToString();}public static void ThreadCallback(IAsyncResult data){Console.WriteLine("ThreadCallback = > " + data.AsyncState);}static void Main(string[] args){var mydelegate = new MyDelegate(Thread1);IAsyncResult result = mydelegate.BeginInvoke("Thread1 Para", ThreadCallback, "Callback Para");//异步执⾏完成var resultstr = mydelegate.EndInvoke(result);Console.WriteLine(resultstr);Console.ReadKey();}}}委托异步执⾏⽰例代码三、线程同步线程同步:指多个线程协同、协助、互相配合。
(二)线程创建、中止、中断、线程Join、优先级、调度
(⼆)线程创建、中⽌、中断、线程Join、优先级、调度线程的基本创建import java.util.concurrent.ExecutionException;/*** @author monco* @date 2020/5/18* @description: 创建新线程*/public class CreateThread {/*** 继承 Thread 类实现新线程创建*/private static class UseThread extends Thread {// 重写⽗类⽅法@Overridepublic void run() {super.run();System.out.println("i am a new Thread");}}private static class UseRunnable implements Runnable {// 实现接⼝public void run() {System.out.println("I am implements Runnable");}}public static void main(String[] args)throws InterruptedException, ExecutionException {// 适⽤创建新线程的start⽅法UseThread useThread = new UseThread();useThread.start();// 适⽤接⼝需要将实现 Runnable 对象的类作为参数传⼊ Thread对象中// Runnable 接⼝只有⼀个run⽅法没有 start⽅法实际还是适⽤ Thread 对象的start⽅法UseRunnable useRunnable = new UseRunnable();new Thread(useRunnable).start();}}线程的中⽌⾃然两种情况:1.线程中的⽅法执⾏完毕2.抛出了⼀个未处理的异常导致线程提前结束⼿动中⽌暂停、恢复和停⽌操作对应在线程Thread的API就是suspend()、resume()和stop()。
越大优先级越高,优先级越高被OS选中的可能性就越大
越⼤优先级越⾼,优先级越⾼被OS选中的可能性就越⼤进程的休眠:Thread sleep(1000);//括号中以毫秒为单位当main()运⾏完毕,即使在结束时时间⽚还没有⽤完,CPU也放弃此时间⽚,继续运⾏其他程序。
Try{Thread.sleep(1000);}Catch(Exception e){e.printStackTrace(e);}T1.join()表⽰运⾏线程放弃执⾏权,进⼊阻塞状态。
当t1结束时,main()可以重新进⼊运⾏状态。
T1.join实际上是把并发的线程编程并⾏运⾏。
线程的优先级:1-10,越⼤优先级越⾼,优先级越⾼被OS选中的可能性就越⼤。
(不建议使⽤,因为不同操作系统的优先级并不相同,使得程序不具备跨平台性,这种优先级只是粗略地划分)。
注:程序的跨平台性:除了能够运⾏,还必须保证运⾏的结果。
1package TomTexts;2import java.io.*;3import java.util.Date;45public class TomTexts_36 {6public static void main(String []args)7 {8 String filename="d:\\javapj\\ex.java";9 File myfile=new File(filename);10if(!myfile.exists() )11 {12 System.err.println(filename+"未找到!");13return;14 }15if( myfile.isDirectory() )16 {17 System.err.println("⽂件对象"+myfile.getName()+"是⽬录!");18 File ds=new File("mydata");19if(!ds.exists())20 {21 ds.mkdir();22 System.out.println("⽬录"+ds.getAbsolutePath()+"创建结束!");23 }24return;25 }26if(myfile.isFile())27 {28 System.out.println("⽂件对象:"+myfile.getAbsolutePath());29 System.out.println("⽂件字节数:"+myfile.length());30 System.out.println("⽂件是否能读:"+myfile.canRead());31if(myfile.canWrite())32 {33 System.out.println("设置⽂件为只读:"+myfile.setReadOnly());34 }35 System.out.println("⽂件是否可写:"+myfile.canWrite());36 Date fd=new Date(stModified());37 System.out.println("⽂件上次修改时间:"+fd.toString());38 }39 }4041 }。
多线程考试题及答案
多线程考试题及答案一、单选题(每题2分,共10分)1. 在Java中,哪个类是用来创建线程的?A. ThreadB. RunnableC. CallableD. ExecutorService答案:A2. 线程的优先级范围是多少?A. 1-10B. 0-5C. 1-5D. 0-10答案:A3. 线程的生命周期中,哪个状态表示线程正在执行?A. 新建(New)B. 可运行(Runnable)C. 阻塞(Blocked)D. 死亡(Terminated)答案:B4. 在Java中,哪个方法是用于启动线程的?A. start()B. run()C. join()D. sleep()答案:A5. 线程同步可以使用哪种关键字?A. finalB. volatileC. synchronizedD. transient答案:C二、多选题(每题3分,共15分)1. 以下哪些是线程间通信的方式?A. wait()和notify()B. wait()和notifyAll()C. join()D. 共享资源答案:ABCD2. 在Java中,哪些是创建线程的正确方式?A. 继承Thread类B. 实现Runnable接口C. 实现Callable接口D. 使用ExecutorService答案:ABCD3. 线程的哪些状态表示线程不在运行?A. 可运行(Runnable)B. 阻塞(Blocked)C. 等待(Waiting)D. 睡眠(Sleeping)4. 以下哪些是线程池的类型?A. 固定大小的线程池B. 可缓存的线程池C. 单线程执行器D. 定时以及周期性执行的线程池答案:ABCD5. 线程安全问题通常发生在哪些情况下?A. 多个线程访问同一个资源B. 一个线程在执行过程中被中断C. 多个线程对共享资源进行写操作D. 线程执行顺序不确定答案:ACD三、判断题(每题2分,共10分)1. 线程一旦启动,就无法停止。
C++线程优先级SetThreadPriority的使用实例
DWORD WINAPI ThreadProcNormal(LPVOID lpParameter) {
for (int i=0;i<20;i++) {
printf("I'm in thread Normal...\n"); } return 0; }
//等待两个线程结束 ::WaitForMultipleObjects(2,hThread,TRUE,INFINITE); ::CloseHandle(hThread[0]); ::CloseHandle(hThread[1]); return 0; }
希望本文所述对大家的C++程序设计有所帮助。
hThread[1] = ::CreateThread(NULL,0, ThreadProcNormal, NULL, CREATE_SUSPENDED, &dwThreadIdNormal); ::SetThreadPriority(hThread[1],THREAD_PRIORITY_NORMAL); ::ResumeThread(hThread[1]);
复制代码 代码如下: // ThreadPriority.cpp : 定义控制台应用程序的入口点。 //
#include "stdafx.h" #include <Windows.h>
DWORD WINAPI ThreadProcIdle(LPVOID lpParameter) {
for (int i=0;i<20;i++) {
线程优先级设定标准
线程优先级设定标准因操作系统和编程语言而异。
在Java中,线程优先级是一个int变量,范围从1到10,1代表最低优先级,10代表最高优先级。
默认优先级是5。
可以通过setPriority()方法来设置线程的优先级。
然而,需要注意的是,线程的优先级通常只作为一种提示,不一定能够决定线程的执行顺序。
操作系统会有自己的调度算法来决定哪个线程能够运行。
另外,设置高优先级也可能导致饥饿,因为高优先级的线程可能会占用过多的CPU时间,导致低优先级的线程无法得到执行。
因此,建议不要过度依赖线程的优先级来控制线程的执行顺序。
以上信息仅供参考,如有需要,建议咨询相关领域的专家。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
线程优先级每个线程都有一个“优先级”,范围是0~31,0为最低优先级,31为最高优先级。
当系统决定哪个线程需要调度的时候,首先查看是否存在优先级为31的可调度线程,如果存在,就从中选择一个进行调度。
当该线程的时间片到达之后,系统查看是否存在另一个优先级为31的可调度线程,如果存在,就调度它。
只要有一个可调度的优先级为31的线程存在,那么系统绝对不会调度优先级为0~30的线程,这样会导致其他线程“饥饿”。
高优先级线程往往“打断”低优先级线程的执行。
比如,当一个优先级为15的线程正在运行,如果此时系统发现一个优先级比15高的线程可以调度,那么该高优先级线程会“打断”那个低优先级线程的执行,哪怕低优先级的时间片才过了一半。
另外,当系统引导的时候,系统创建一个特殊的线程,称为“zero page”(0页)线程,该线程是整个系统中唯一一个优先级为0(最低)的线程。
当系统没有任何线程需要执行的时候,该线程负责将系统中所有RAM页面清零(也就是资源回收)。
线程优先级有一个抽象层的概念。
由于一些历史的原因,微软并没有将线程调度程序的行为完全固定下来。
微软没有让应用程序充分利用调度程序的特性。
微软宣称这个调度程序的行为是变化,在编程的时候需要注意。
由这几点可见,你的应用程序可以有自己的调度特性。
Windows API充分反映了系统调度的一个抽象层。
如此,就不会直接与系统的调度程序通信,相反,可以调用API函数,根据系统的版本的不同转换这些参数。
这一层,就是线程优先级的抽象层。
下面详细叙述这个抽象层究竟有哪些内容。
对于进程而言,Windows有一个“优先级类”的概念。
这些优先级类作用与进程中的所有线程。
Windows 2000/XP/2003/Vista支持6个“优先级类”:1、Real-time:实时2、High:高3、Above normal:高于标准4、Normal:标准5、Below normal:低于标准6、Idle:空闲。
一个进程应该避免使用“实时”优先级类,因为使用该优先级类会导致其他进程中的线程很难被调度,甚至会打断或者抢占系统线程的执行。
“高”优先级类也应该尽量避免,除非有特殊的工作需要使用这个优先级。
当一个进程的“优先级类”被确定以后,就只需要考虑该进程内部各个线程之间的优先级关系。
对于进程中的线程而言,有一个“相对线程优先级”的概念,这可以决定一个进程中多个线程之间的优先级关系。
Windows支持7种“相对线程优先级”:1、Time-critical:关键时间(最高的相对线程优先级)2、Heightest:最高(翻译是这么翻译,但是并不是最高的相对线程优先级)3、Above normal:高于标准4、Normal:标准5、Below normal:低于标准6、Lowest:最低(翻译是这么翻译,但是并不是最低的相对线程优先级)7、Idle:空闲这里并没有提到有关0~31的优先级的任何内容。
开发者从来不用具体设置一个线程的优先级,也就是不需要将一个线程优先级设置为0~31中的一个。
操作系统负责将“优先级类”和“相对线程优先级”映射到一个具体的优先级上。
这种映射方式,是随Windows版本的不同而不同的。
以下是Windows 2000/XP/2003/Vista的线程优先级映射方式:线程相对优先级进程优先级类Idle Below Normal Normal Above Normal High Real-TimeTime-critical 15 15 15 15 15 31 Highest 6 8 10 12 15 26 Above normal 5 7 9 11 14 25 Normal 4 6 8 10 13 24 Below normal 3 5 7 9 12 23 Lowest 2 4 6 8 11 22 Idle 1 1 1 1 1 16仔细查看该表,现在知道为什么最好不要将“进程优先级类”设置为“实时”了吧,因为一个进程如果具有“实时”的优先级类,那么该进程中的所有线程的优先级(最低也有16)比任何具有其他优先级类的进程中的线程的优先级(最高只有15)都要高。
这样会导致其他优先级类低于“实时”的进程中的线程无法得到调度。
要注意的是,“优先级类”是一个抽象的概念,是对于一个进程而言的,但是不是说进程是可以调度的,只有线程是可以调度的。
微软提出这个概念,仅仅只是为了帮助你将它与调度程序的内部运行的情况区分起来。
“优先级类”应该是可以影响一个进程中所有线程的优先级的。
上面讲了有关线程优先级的内容,包括线程的“具体优先级”,“优先级抽象层”的内容(进程“优先级类”、“线程相对优先级”等)。
下面主要讲述如何在编程中设置线程的优先级。
一个进程,往往关联一个“优先级类”,你可以在CreateProcess函数的fdwCreate参数中设置这个优先级类的具体内容,可以有6种选择,对于6种优先级类:1、REALTIME_PRIORITY_CLASS:Real-time,实时优先级类2、HIGH_PRIORITY_CLASS:High,高优先级类3、ABOVE_NORMAL_PRIORITY_CLASS:Above normal,高于标准4、NORMAL_PRIORITY_CLASS:Normal,标准5、BELOW_NORMAL_PRIORITY_CLASS:Below normal:低于标准6、IDLE_PRIORITY_CLASS:Idle,空闲也可以更改一个特定的进程优先级类,通过呼叫SetPriorityClass函数可以到达这个目的。
BOOL SetPriorityClass(HANDLE hProcess, //指定的进程句柄DWORD fdwPriority); //优先级类(对应上面6种取值)例如,下面的代码设置当前进程的优先级类为空闲:SetPrioriytClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);当然,可以获得某一个进程的优先级类,通过呼叫GetPriorityClass函数:DWORD GetPriorityClass(HANDLE hProcess);该函数返回的值就是对应6个优先级类的值中的一个。
当一个线程被创建,它的“线程相对优先级”默认为normal(标准)。
CreateThread函数没有提供设置线程相对优先级的功能。
可以调用SetThreadPriority函数设置一个线程的相对优先级。
BOOL SetThreadPriority(HANDLE hThread, //指定的线程句柄int nPriority); //线程相对优先级(取值对应如下)该函数接受一个线程句柄和线程相对优先级取值,设置对应的线程的相对优先级。
该线程相对优先级取值如下:1、THREAD_PRIORITY_TIME_CRITICAL:Time-critical,关键时间(最高)2、THREAD_PRIORITY_HIGHEST:Highest,最高(其实是“次高”)3、THREAD_PRIORITY_ABOVE_NORMAL:Above normal,高于标准4、THREAD_PRIORITY_NORMAL:Normal,标准5、THREAD_PRIORITY_BELOW_NORMAL:Below normal,低于标准6、THREAD_PRIORITY_LOWEST:Lowest,最低(其实是“次低”)7、THREAD_PRIORITY_IDLE:Idle,空闲(最低)你可以呼叫GetTreadPriotiry函数取得一个特定线程的相对优先级。
int GetThreadPriority(HANDLE hThread); //函数返回上述7个取值为了创建一个线程相对优先级不是标准的线程,比如要创建一个高于标准的线程,你可以传递CREATE_SUSPENDED参数给CreateThread,从而创建一个起始状态为“挂起”的线程,然后调用SetThreadPriority函数设置该线程的相对优先级,然后调用ResumeThread函数恢复该线程的运行。
代码如下:DWORD dwThreadID;HANDLE hThread = CreateThread(NULL, 0, ThreadFunc, NULL,CREATE_SUSPENDED, &dwThreadID); SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);ResumeThread(hThread);CloseHandle(hThread);操作系统会动态地提高线程的基础优先级等级(0~31),一般是为了响应一些I/O事件。
有的时候,系统动态地提高线程优先级会带来不便。
你可以呼叫SetProcessPriorityBoost 和SetThreadPriorityBoost函数来通知系统是否需要动态提高线程优先级。
BOOL SetProcessPriorityBoost(HANDLE hProcess,BOOL bDisablePriorityBoost);BOOL SetThreadPriorityBoost(HANDLE hThread,BOOL bDisablePriorityBoost);这两个函数的第二个参数用于通知系统是否要动态提高指定进程的优先级类和指定线程的相对优先级。
也可以使用以下两个函数得到这些信息:BOOL GetProcessPriorityBoost(HANDLE hProcess,PBOOL pbDisablePriorityBoost);BOOL GetThreadPriorityBoost(HANDLE hThread,PBOOL pbDisablePriorityBoost);。