精华内容
下载资源
问答
  • 任务管理器改优先级
    千次阅读
    2018-09-30 15:19:02

    网上找了下java里的异步任务调度器,很多,但没有基于优先级队列的(或者我没发现),于是我写了一个。

    前方干货预警!

    一共四个文件。
    AloneTask.java(带有优先级的任务类)
    ComparableThreadPoolExecutor.java(带有比较器的线程池)
    NamedThreadFactory.java(可命名线程池,这个不是必须的)
    Scheduler.java(调度器,找了网上的一份改了下)

    AloneTask这里加了很多项目里的东西,比如用了spring的依赖注入来获取任务类名,还有slf4j的日志工具,还有自己写的Util空判断器。遇上异常可以删掉那块或者留言,核心的地方不会有异常。

    import java.lang.reflect.Method;
    import java.util.concurrent.Callable;
    
    import org.slf4j.Logger;
    
    public class AloneTask<T> implements Callable<T>, Comparable<AloneTask<T>>, Runnable {
    	private static final Logger logger = Loggers.asyncLogger;
    
    	Object service;
    	String method;
    	Object[] params;
    	String trace;//调用任务的堆栈,性能较低,上线时注释 TODO
    	int priority;
    
    	public AloneTask(T service, String method, int priority, Object... params) {
    		super();
    		if (service instanceof String) {
    			this.service = Config.ctx.getBean((String) service);
    		} else {
    			this.service = service;
    		}
    		this.priority = priority;
    		this.method = method;
    		this.params = params;
    		this.trace = Util.getCallStack();
    	}
    
    	@Override
    	@SuppressWarnings("unchecked")
    	public T call() throws Exception {
    		if (service == null || Util.isEmpty(method)) {
    			logger.error("参数异常,无法完成任务.调用堆栈:" + this.trace);
    			return null;
    		}
    		long startTime = System.currentTimeMillis();
    		T future = (T) getMethod().invoke(this.service, this.params);
    		long useTime = (startTime - System.currentTimeMillis()) / 1000;
    		if (useTime > 10) {
    			logger.warn("call cost time too long,time " + useTime + "s,task method:" + this.method);
    		}
    		return future;
    	}
    	
    	@Override
    	public void run() {
    		if (service == null || Util.isEmpty(method)) {
    			logger.error("参数异常,无法完成任务.调用堆栈:" + this.trace);
    			return;
    		}
    		long startTime = System.currentTimeMillis();
    		try {
    			getMethod().invoke(this.service, this.params);
    		} catch (Exception e) {
    			logger.error("异步任务异常,任务所在线程:" + Thread.currentThread().getName() + " 异常详细信息:\n" + e.getMessage() + "\n任务调用堆栈:" + this.trace);
    		}
    		long useTime = (startTime - System.currentTimeMillis()) / 1000;
    		if (useTime > 10) {
    			logger.warn("call cost time too long,time " + useTime + "s,task method:" + this.method);
    		}
    	}
    
    	/*
    	 * 获取被调用的方法
    	 */
    	private Method getMethod() {
    		Method m = null;
    		try {
    			Class<?>[] paramsClass = new Class[this.params.length];
    			for (int i = 0; i < this.params.length; i++) {
    				paramsClass[i] = this.params[i].getClass();
    			}
    			m = this.service.getClass().getDeclaredMethod(this.method, paramsClass);
    		} catch (Exception e) {
    			Method[] allMethods = this.service.getClass().getDeclaredMethods();
    			for (Method mRec : allMethods) {
    				if (mRec.getName().equals(this.method)) {
    					Class<?>[] methodParamsTypes = mRec.getParameterTypes(); // 找到同名函数的参数类型
    					if (methodParamsTypes.length == this.params.length) {
    						boolean flag = true;
    						for (int i = 0; i < methodParamsTypes.length; i++) {
    							if (null != this.params[i]) {
    								if (!match(this.params[i], methodParamsTypes[i])) {
    									flag = false;
    									break;
    								}
    							}
    						}
    						if (flag) {
    							m = mRec;
    							break;
    						}
    					}
    				}
    			}
    		}
    
    		if (null == m) {
    			logger.info(String.format("未找到[%s]的[%s]方法完成任务.", this.service.getClass().toString(), this.method));
    		} else {
    			m.setAccessible(true);// 设置访问域以允许访问private和protected方法
    		}
    		return m;
    	}
    
    	/**
    	 * 判断参数类型是否匹配
    	 * 
    	 * @param c
    	 *            参数类型
    	 * @param pc
    	 *            方法参数类型
    	 * @return
    	 */
    	private boolean match(Object p, Class<?> pc) {
    		boolean isMatch = true;
    		if (pc.isPrimitive()) { // 方法参数是基本类型
    			if (!pc.equals(getPrimitiveClass(p.getClass()))) {
    				isMatch = false;
    			}
    		} else {
    			if (!pc.isInstance(p)) {
    				isMatch = false;
    			}
    		}
    		return isMatch;
    	}
    
    	private static Class<?> getPrimitiveClass(Class<?> c) {
    		Class<?> pc = null;
    		if (c.equals(Long.class)) {
    			pc = long.class;
    		} else if (c.equals(Integer.class)) {
    			pc = int.class;
    		} else if (c.equals(Double.class)) {
    			pc = double.class;
    		} else if (c.equals(Float.class)) {
    			pc = float.class;
    		} else if (c.equals(Short.class)) {
    			pc = short.class;
    		} else if (c.equals(Byte.class)) {
    			pc = byte.class;
    		} else if (c.equals(Character.class)) {
    			pc = char.class;
    		} else if (c.equals(Boolean.class)) {
    			pc = boolean.class;
    		}
    		return pc;
    	}
    
    	//比较优先级
    	@Override
    	public int compareTo(AloneTask<T> o) {
    		if (this.priority < o.priority) {
    			return -1;
    		}
    		if (this.priority > o.priority) {
    			return 1;
    		}
    		return 0;
    	}
    }
    

    ComparableThreadPoolExecutor.java

    public class ComparableThreadPoolExecutor extends ThreadPoolExecutor {
    
    	public ComparableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
    			BlockingQueue<Runnable> workQueue) {
    		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    	}
    
    	public ComparableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
    			BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
    		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
    	}
    
    	public ComparableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
    			BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
    		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    	}
    
    	public ComparableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
    			BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
    		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    	}
    
    	@Override
    	protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
    		return new ComparableFutureTask<>(runnable, value);
    	}
    
    	@Override
    	protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
    		return new ComparableFutureTask<>(callable);
    	}
    
    	protected class ComparableFutureTask<V> extends FutureTask<V> implements Comparable<ComparableFutureTask<V>> {
    		private Object object;
    
    		public ComparableFutureTask(Callable<V> callable) {
    			super(callable);
    			object = callable;
    		}
    
    		public ComparableFutureTask(Runnable runnable, V result) {
    			super(runnable, result);
    			object = runnable;
    		}
    
    		@Override
    		@SuppressWarnings({ "unchecked", "rawtypes" })
    		public int compareTo(ComparableFutureTask<V> o) {
    			if (this == o) {
    				return 0;
    			}
    			if (o == null) {
    				return -1; // 内容为null的任务排在队尾
    			}
    			if (object != null && o.object != null) {
    				if (object.getClass().equals(o.object.getClass())) {
    					if (object instanceof Comparable) {
    						return ((Comparable) object).compareTo(o.object);
    					}
    				}
    			}
    			return 0;
    		}
    	}
    }
    

    NamedThreadFactory.java 给线程起个名字方便debug和管理。

    public class NamedThreadFactory implements ThreadFactory {
    	
    	private AtomicInteger order = new AtomicInteger(0);
    	
    	private String name;
    	
    	public NamedThreadFactory(String name) {
    		this.name = name;
    	}
    
    	@Override
    	public Thread newThread(Runnable r) {
    		Thread thread = new Thread(r);
    		thread.setName(name + "  ORDER:" + order.getAndIncrement());
    		return thread;
    	}
    	
    }
    

    Scheduler.java,我预先放了5个优先级,可以外部定义(记得改ComparableThreadPoolExecutor的compareTo)。

    public class Scheduler {
    	private static final Scheduler instance = new Scheduler();
    	private static ExecutorService executorServie;
    	
    	private static final int CORE_POOL_SIZE = 10;
    	private static final int MAXIMUM_POOL_SIZE = 10;
    
    	private Scheduler() {
    		executorServie = new ComparableThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, 1, 
    														  TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>(),
    														  new NamedThreadFactory("Scheduler任务调度器子线程"));
    	}
    
    	@Bean(name = "Bmall.Scheduler", initMethod = "init", destroyMethod = "shutdown")
    	public static Scheduler getInstance() {
    		return instance;
    	}
    	
    	public void init() {
    		
    	}
    
    	public void shutdown() {  
    		executorServie.shutdown();
        }
    
    	/**
    	 * 将任务存入任务队列中。支持存private和protected方法。
    	 * @param service 类名(必须注册为spring的bean)或其实例
    	 * @param method 方法名
    	 * @param priority 优先级
    	 * @param params 参数
    	 */
    	@SuppressWarnings("unchecked")
    	public <T> void call(T service, String method, PRIORITY priority, T... params) {
    		Runnable runnable = new AloneTask<T>(service, method, priority.getValue(), params);
    		executorServie.execute(runnable);
    	}
    	
    	/**
    	 * 将任务存入任务队列中并返回future。支持存private和protected方法。
    	 * @param service 类名(必须注册为spring的bean)或其实例
    	 * @param method 方法名
    	 * @param priority 优先级
    	 * @param params 参数
    	 * @return future可用于回调
    	 */
    	@SuppressWarnings("unchecked")
    	public <T> Future<T> callBack(T service, String method, PRIORITY priority, T... params){
    		Callable<T> callback = new AloneTask<T>(service, method, priority.getValue(), params);
    		Future<T> future = executorServie.submit(callback);
    		return future;
    	}
    	
    	public enum PRIORITY {
    		/** 最低级别 */
    		LOWEST(5),
    		
    		/** 需要一段时间后执行的级别 */
    		LOW(4),
    		
    		/** 默认级别*/
    		NORMAL(3),
    		
    		/** 很可能马上就需要执行的级别 */
    		HIGH(2),
    		
    		/** 需要立即执行的级别*/
    		HIGHEST(1);
    		
    		private final int value;
    
    	    // 构造器默认也只能是private, 从而保证构造函数只能在内部使用
    	    private PRIORITY(int value) {
    	        this.value = value;
    	    }
    
    	    public int getValue() {
    	        return value;
    	    }
    	}
    
    }
    

    具体使用方法:(将print任务以中优先级放入队列中执行)

    public void print(String str) {
    	System.out.println(str);
    }
    
    public static void main(String[] args) {
    	Scheduler.getInstance().call(this, "print", PRIORITY.NORMAL, "打印的内容");
    }
    

    需要注意的是Scheduler里的call()方法的异常会直接打印,而callback()里的异常会被存在返回值中。

    更多相关内容
  • [FreeRtos]任务状态切换和优先级设置

    千次阅读 2021-08-10 20:29:52
    a: 调用xTaskCreate()函数将新建一个任务,新建的任务会加入到就绪列表,若新建的任务优先级足够高,调度会立即将CPU资源分配给他,使它进入运行态。 b: 调度检查就绪列表中优先级高的任务,并将CPU资源分配...

    1. 任务状态的切换

    FreeRTOS中任务的状态可分为:未创建态、就绪态、运行态、挂起态、延时态五种状态。

    a: 调用xTaskCreate()函数将新建一个任务,新建的任务会加入到就绪列表,若新建的任务的优先级足够高,调度器会立即将CPU资源分配给他,使它进入运行态

    b: 调度器检查就绪列表中优先级高的任务,并将CPU资源分配给它,使他进入运行态

    c: 运行态的任务可能创建/恢复了新的更高优先级的任务,或者因其操作了某事件(如发送了一个更高优先级的任务需要的消息),使更高优先级的任务进入了就绪表时,再或者更高优先级的任务延时到期自动加入就绪表时,更高优先级的任务将得到CPU资源,使当前运行的任务重新进入就绪态(虽然他还在就绪列表,但由于优先级低,而不被分配CPU资源)。

    d: 任务对申请处理的事件操作成功、或者处理失败但发起获取申请时设置阻塞时间为0,将继续保留CPU资源,继续运行。

    e: 正在运行的任务(毫无疑问,此时它是就绪表中优先级最高的任务之一),可能想要处理一个事件(如想获取一条消息队列中的消息),此时它将向事件资源管理者(即消息队列)发起申请。如使用以下函数尝试获取队列中的一条消息:

    xQueueReceive( QueueHandle_t xQueue,void * pvBuffer,TickType_t xTicksTowait );

    f: 任务对申请处理的事件操作失败、并且发起获取申请时设置阻塞时间大于0,则任务会从就绪列表,加入到阻塞延时列表;在等待期间尝试操作事件成功。

    n: 运行态的任务调用vTaskDelay(),将把自己从就绪列表搬移到主动延时列表,并让就绪表的其他任务获取CPU资源。

    h: 延时态的任务在延时结束时,若优先级比当前任务优先级高,就加入就绪队列,并立即获得CPU资源,进入运行。

    g: 延时态的任务在延时结束时,若优先级比当前任务优先级低,就加入就绪队列,但是由于优先级不够,只能等待获取CPU资源。

    i: 处于就绪态的任务被正在执行的高优先级的任务挂起,将从就绪列表加入到挂起列表,注意,在挂起列表中的任务,是被打入“冷宫”的任务,除非程序员在写代码时主动调用vTaskResume ()恢复该任务,否则该该任务永远不会回到就绪列表了,更不会被执行。

    j: 运行态的任务,主动调用vTaskSuspend()函数挂起自己,将使自己从就绪列表加入挂起列表,并立即执行就绪列表中优先级高的其他任务。

    k: 挂起态的任务,不会获得CPU资源了,因此只能等待被正在运行的任务(或中段)唤醒。m: 同上,被唤醒的任务会被从挂起列表加入到就绪列表,若被唤醒的任务的优先级比当前正在运行的任务优先级高,就立即将CPU资源分配给被唤醒的任务。

    当然,我们还可以使用vTaskDelete()函数删除一个任务,删除一个任务会将该任务变为未创建态(它什么资源都没有了),除非重新调用vTaskCreat()函数重建它,否则永远不会加入到就绪列表了。

    特别地,挂起一个处于延时态的任务会是什么情况,可以再具体讨论。

    2.运行态的任务触发切换的情况总结


            a. 正在运行的任务,触发调度器工作的途径有:(但凡有可能引出高优先级任务或中断的操作都会触发调度器检查)

        1.创建新任务(显然,新建任务可能比自身的优先级高,因此可能触发调度器) 

        2.挂起自己、删除自己(往往代表我执行完了)、阻塞延时自己、普通延时自己

        3.解阻塞高优先级任务、或触发中断(中断中解阻塞一些高优先级任务)

        4.高优先级任务自动就绪(主要指高优先级任务延时结束,定时器任务,定时器任务优先级较  高的情况下,若定时溢出,将抢占CPU)

        5.恢复一个挂起的高优先级任务。

    b. 中断中触发调度器工作的途径有:(但凡有可能使高优先级任务就绪的操作都会触发调度器检查)

        1.在中断处理函数中创建新的高优先级任务

        2.在中断中释放信号量、消息等使高优先级任务解除阻塞进入就绪。

        3.恢复优先级高的任务

    3.任务优先级分配方案


    对于初学者,有时候会纠结任务优先级设置为多少合适,因为任务优先级设置多少是没有标准的。对于这个问题,我们这里为大家推荐一个标准,任务优先级设置推荐方式如下图13.1 所示:
    在这里插入图片描述

     

     IRQ 任务:IRQ 任务是指通过中断服务程序进行触发的任务,此类任务应该设置为所有任务里面优先级最高的。

     高优先级后台任务:比如按键检测,触摸检测,USB 消息处理,串口消息处理等,都可以归为这一类任务。

     低优先级的时间片调度任务:比如 emWin 的界面显示,LED 数码管的显示等不需要实时执行的都可以归为这一类任务。 实际应用中用户不必拘泥于将这些任务都设置为优先级 1 的同优先级任务,可以设置多个优先级,只需注意这类任务不需要高实时性。
     空闲任务:空闲任务是系统任务。
     特别注意:IRQ 任务和高优先级任务必须设置为阻塞式(调用消息等待或者延迟等函数即可),只有这样,高优先级任务才会释放 CPU 的使用权,,从而低优先级任务才有机会得到执行。
    这里的优先级分配方案是我们推荐的一种方式,实际项目也可以不采用这种方法。 调试出适合项目需求的才是最好的。

    4. 中断优先级和任务优先级区别


            部分初学者也容易在这两个概念上面出现问题。 简单的说,这两个之间没有任何关系,不管中断的优先级是多少,中断的优先级永远高于任何任务的优先级,即任务在执行的过程中,中断来了就开始执行中断服务程序。
            另外对于 STM32F103,F407 和 F429 来说,中断优先级的数值越小,优先级越高。 而 FreeRTOS的任务优先级是,任务优先级数值越小,任务优先级越低。

     

     

    展开全文
  • FreeRTOS调度是唯一可以切换任务状态的实体。 非运行态 阻塞态 等待事件的任务处于阻塞态,任务会因等待两种不同的事件进入阻塞态 时间相关事件-此类事件要么是一个延时的相对时间,要么是一个

    任务状态

    运行态

    任务分为运行态和非运行态两种,在处理器运行过程中,任一时刻只能有一个任务处于运行态,非运行态又包含很多子态。

    当任务处于非运行态时,任务处于休眠态(dormant),它的状态被保存,以便下一次调度程序决定它应该进入运行态。当一个任务恢复执行时,它从最后一次离开运行态之前将要执行的指令开始执行。

    在这里插入图片描述

    FreeRTOS调度器是唯一可以切换任务状态的实体。

    非运行态

    阻塞态

    等待事件的任务处于阻塞态,任务会因等待两种不同的事件进入阻塞态

    1. 时间相关事件-此类事件要么是一个延时的相对时间,要么是一个要到达的绝对时间。例如,任务可能会进入阻塞态等待10ms通过
    2. 同步事件-此类事件源自另外一个任务或中断

    FreeRTOS中消息队列、二值信号量、计数型信号量、互斥信号量、递归互斥信号量、时间标志组、任务通知都会产生同步事件

    挂起态

    调度器不能条用处于挂起状态的任务。进入挂起状态的唯一方法是通过调用vTaskSuspend() API函数,解除挂起状态的方法是通过调用vTaskResume()或xTaskResumeFromISR() API函数。大多数应用程序不使用挂起状态

    就绪态

    任务既不是运行态,也不是处于阻塞态或挂起态,则被认为是就绪态。这些任务能够运行,因此准备即将运行,但此时并未处在运行状态

    在这里插入图片描述
    创建 任务 到 就 绪 态 : 任务创建完成后进入就 绪 态,表明任务已准备就绪,只等待调度器进行调度即可运行。

    就 绪 态 到 运行 态 :调度器发生任务切换 时,就绪列表中最高优先级的任务优先执行,进入运行态

    运行 态 到 就 绪 态 : 创建或还原更高优先级的任务后,将进行任务调度 。 此 时 ,就 绪列表中优先级最高的任务将变为运行状态 。 然 后 , 原 始 正在 运行 的 任务 将 从运行 状态 更 改 为 就 绪 状 态 , 并 位 于 就 绪 列 表 中 。 更 高 优先 级 任务 运行 结束 后 ,继续运行原始任务。

    运行 态 到 阻塞 态 : 正在 运行 的 任务 发 生 阻 塞(挂 起 、 延 时 、 读 信号 量 等 待 )时 , 该 任务 会 从 就 绪 列 表 中 删除 , 任 务 状态 由 运行 态 变 成 阻塞 态 , 然 后 发 生 任 务切换 , 运 行 就 绪 列 表 中 当前 最 高 优先 级 任务 。

    阻塞 态 到 就 绪 态 : 阻塞 的 任务 被 恢复 后 (任务 恢复 、 延 时 时 间 超 时 、 读信号量 超 时 或 读 到 信号 量 等 ) 此 时 被 恢复 的 任务 会 被 加 入 就 绪 列 表 , 从 而 由 阻塞 态 变成就绪态;如果此时被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换,将该任务将再次转换任务状态,由就绪态变成运行态。

    就绪态、阻塞态、运行态到挂起态:任务可以通过调用vTaskSuspend()API函数可以将处于任何状态的任务挂起,被挂起的任务得不到CPU的使用权,也不会参与调度,除非它从挂起态中解除。

    挂起态到就绪态:把一个挂起状态的任务恢复的唯一途径就是调用VTaskResume()或vTaskResumeFromISR()API函数,如果此时被恢复任务的优先级高于正在运行任务的优先级,则会发生任务切换,将该任务将再次转换任务状态,由就绪态变成运行态。

    创建任务

    xTaskCreate() API

    BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
    					  const char * const pcName,
    					  uint16_t usStackDepth,
    					  void *pvParameters,
    					  UBaseType_t uxPriority,
    					  TaskHandle_t *pxCreatedTask );
    
    Parameters NameDescription
    pvTaskCode该参数是一个指向实现该任务的函数的指针(事实上,是函数名)
    pcName人为自定义的任务名称 (FreeRTOS.h中的宏定义 configMAX_TASK_NAME_LEN 定义了任务名的字符串最大长度,超过此长度,会被截断)
    usStackDepth该参数是任务堆栈空间的深度大小(任务在被创建时,由内核分配专属于自己的堆栈空间),单位是Words (字),而非Bytes(字节),例如32位宽的栈空间,usStackDepth=100,此堆栈空间分配400 字节(100 * 4 =400Bytes),堆栈深度*堆栈宽度的大小不得超过unit_16类型变量的最大值
    pvParameters传递给任务函数的值(void * 类型),若无参数传递,则为NULL
    uxPriority任务优先级,范围:0-----(configMAX_PRIORITIES – 1)
    pxCreatedTask任务句柄,可用于更改任务优先级或删除任务等,如果不使用任务句柄,可以设置为NULL
    Returned value返回pdPASS,表示任务创建成功,返回pdFALL,表示创建失败,可能是因为堆栈空间不够

    例程

    void vTask1( void *pvParameters )  //任务函数1
    {
    	const char *pcTaskName = "Task 1 is running\r\n";
    	volatile uint32_t ul; /* volatile to ensure ul is not optimized away. */
    	/* As per most tasks, this task is implemented in an infinite loop. */
    	for( ;; )
    	{
    		/* Print out the name of this task. */
    		vPrintString( pcTaskName );
    		/* Delay for a period. */
    		for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
    		{
    		}
    	}
    }
    
    void vTask2( void *pvParameters )  //任务函数2
    {
    	const char *pcTaskName = "Task 2 is running\r\n";
    	volatile uint32_t ul; /* volatile to ensure ul is not optimized away. */
    	/* As per most tasks, this task is implemented in an infinite loop. */
    	for( ;; )
    	{
    		/* Print out the name of this task. */
    		vPrintString( pcTaskName );
    		/* Delay for a period. */
    		for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
    		{
    		}
    	}
    }
    
    int main( void )
    {
    	xTaskCreate( vTask1, /* Pointer to the function that implements the task. */
    				"Task 1",/* Text name for the task. This is to facilitatedebugging only. */
    				1000, /* Stack depth - small microcontrollers will use muchless stack than this. */
    				NULL, /* This example does not use the task parameter. */
    				1, /* This task will run at priority 1. */
    				NULL ); /* This example does not use the task handle. */
    	/* Create the other task in exactly the same way and at the same priority. */
    	xTaskCreate( vTask2, "Task 2", 1000, NULL, 1, NULL );
    	vTaskStartScheduler();  //开启任务调度器
    
    	for( ;; );
    }
    

    任务内创建任务

    在一个任务中包含另外一个任务,Task1 任务函数中可以创建Task2任务。

    void vTask1( void *pvParameters )
    {
    	const char *pcTaskName = "Task 1 is running\r\n";
    	volatile uint32_t ul; /* volatile to ensure ul is not optimized away. */
    	/*在进入死循环前,创建任务2*/		
    	xTaskCreate( vTask2, "Task 2", 1000, NULL, 1, NULL );
    	for( ;; )
    	{
    		/* Print out the name of this task. */
    		vPrintString( pcTaskName );
    		/* Delay for a period. */
    		for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
    		{
    		}
    	}
    }
    

    任务参数

    使用任务函数参数传递要打印的文本

    void vTask1( void *pvParameters )
    {
    	const char *pcTaskName = "Task 1 is running\r\n";
    	volatile uint32_t ul; /* volatile to ensure ul is not optimized away. */
    	xTaskCreate( vTask2, "Task 2", 1000, NULL, 1, NULL );
    	for( ;; )
    	{
    		/* Print out the name of this task. */
    		vPrintString( pcTaskName );
    		/* Delay for a period. */
    		for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
    		{
    		}
    	}
    }
    
    static const char *pcTextForTask1 = "Task 1 is running\r\n";
    static const char *pcTextForTask2 = "Task 2 is running\r\n";
    int main( void )
    {
    	/* Create one of the two tasks. */
    	xTaskCreate( vTaskFunction, /*任务函数名 */
    				"Task 1", /* 任务名 */
    				1000, /* 任务堆栈空间深度*/
    				(void*)pcTextForTask1, /* 使用任务参数传递要打印的文本 */
    				1, /* 任务优先级 */
    				NULL ); /*此处未用任务句柄 */
    	xTaskCreate( vTaskFunction, "Task 2", 1000, (void*)pcTextForTask2, 1, NULL );
    	
    	vTaskStartScheduler();  //开启任务调度
    
    	for( ;; );
    }
    

    任务优先级

    xTaskCreate() API函数为任务定义了一个初始优先级,这个优先级在调度器运行后可以使用vTaskPrioritySet() API函数来修改

    任务优先级的取值范围为 0 ---- (configMAX_PRIORITIES – 1) ,但不同的任务可以使用共同的任务优先级

    configMAX_PRIORITIES在FreeRTOS.h中定义

    configMAX_PRIORITIES 的最大值取决于使用的方法:

    1. Generic Method(通用方法)

    当使用此种方法,FreeRTOS并不限制configMAX_PRIORITIES可以设置的最大值。但是,它总是明智自动的保持configMAX_PRIORITIES取值不大,因为它的值越高,将消耗更多的RAM,最坏情况执行时间越长

    如果在FreeRTOSConfig.h头文件中将 configUSE_PORT_OPTIMISED_TASK_SELECTION 设置为0,那么将使用泛型方法,或者configUSE_PORT_OPTIMISED_TASK_SELECTION未在头文件中定义,或者泛型方法是使用中的FreeRTOS端口提供的唯一方法

    1. Architecture Optimized Method (架构优化方法)

    架构优化方法使用了少量的汇编代码,其比Generic Method 方法更快。如果使用架构优化的方法,那么configMAX_PRIORITIES不能大于32,与通用方法一样,建议将configMAX_PRIORITIES保持在必要的最小值,因为它的值越高,就越多RAM将被消耗。

    如果在FreeRTOSConfig.h中将configUSE_PORT_OPTIMISED_TASK_SELECTION设置为1,那么将使用架构优化的方法

    FreeRTOS调度器将始终确保能够运行的最高优先级任务是进入运行状态的任务。当多个相同优先级的任务能够运行时,调度器依次将每个任务转换到运行状态或转换出运行状态

    展开全文
  • 全部学习汇总: GitHub - GreyZhang/g_FreeRTOS: learning notes about FreeRTOS.前面简单分析了优先级的获取,实现上很简单。优先级的获取分为一般的OS ...接下来进入临界保护,获取需要修改优先级任务的当前的基础优

    全部学习汇总: GitHub - GreyZhang/g_FreeRTOS: learning notes about FreeRTOS.

    前面简单分析了优先级的获取,实现上很简单。优先级的获取分为一般的OS API还有一个中断安全的版本。在具体的实现上没有太多的代码实现上难理解的地方,仅仅是一个属性的获取。这一次看看优先级的设置实现,不同于优先级的获取,设置其实只有一个接口。

    首先保证设置的优先级数值是合理的,进而根据优先级允许的数目来计算实际的优先级。

    接下来进入临界保护,获取需要修改优先级任务的当前的基础优先级。

    待修改任务的当前基础优先级不等于需要修改的优先级的时候才有修改的需要,如果修改又会分为优先级提升和优先级降低两个可能。因为优先级的提升可能会高过当前正在运行的任务的优先级,这样的话就需要一个任务的切换。但是,高于当前正在运行的优先级又会有两种可能。要么是其他的任务要高于当前的任务,要么是当前任务本身需要提升优先级。针对后者,其实当前任务已经是最高优先级的就绪任务了,那么也就没有了 调度切换的需要了。

    如果修改优先级的任务不是当前的任务,也需要调度的处理。这里设计倒是没有麻烦,最初我还以为会看看次最高就绪优先级,与之做一个对比。

    暂时没有理解uxBasePriority属性的作用,但是从这部分预编译的信息来看,应该是为了支持互斥信号而实现的一种属性状态。

    这部分主要是针对事件功能的支持,目前这个功能我还没有做测试以及分析。看起来,分析完整个FreeRTOS的实现还是需要花点事件的。

    修改了任务的优先级之后,任务可能就不在之前的任务就绪链表中了。因此要有一个移除的处理,这里不需要担心设置相同优先级的情况,因为前面的分支部分已经直接跳过了这样的处理。待处理任务从之前优先级就绪任务链表中移除之后,如果移除之后的链表空了那么应该做一下reset。

    后面这部分容易理解,如果需要进行任务调度的话做一个调度的请求。之后,退出临界保护。

    相比优先级的获取来说,这个的确是多了一点复杂度。主要的差一点在于任务切换的处理,因为优先级的获取不涉及到任何优先级的变化也就不会破坏调度的判断依据。而优先级的设置则有比较大的偏差了,这个可能因为优先级的调整而触发任务调度。因此,多了一点复杂度。但是总体看来,也不是很难。看了很多功能实现分析,然后再考虑下实际的应用,其实在我现在的使用需求下OS应该是能够裁剪到更小的。

    整个OS的机制现在理解下来不是很难理顺,但是并不等同于难度不大,毕竟难点可能都是隐藏于中断保护等细枝末节之中。如果全都考虑清楚了,可能还是需要花很多的功夫的。

    展开全文
  • uCos中的任务机制和优先级位图算法

    千次阅读 2020-04-14 22:18:35
    今天老师上课讲到了uC/OS中的任务机制,所以我想要结合《μC/OS-III源码分析笔记》和中国大学MOOC-电子科技大学《嵌入式系统及应用》PPT写一篇笔记对这部分的内容进行总结。
  • Celery任务优先级管理设计

    千次阅读 2020-08-21 23:42:11
    这边有三类的任务手动、半自动、自动任务,要求优先级手动>半自动>自动。 因为我这边节点只有一个因此也没有使用到分布式,如果分布式的话配置可能更复杂一些。 这边的Celery版本是4.x.x,现有的很多博客都是3...
  • win10永久更改程序优先级-如java.exe

    千次阅读 热门讨论 2021-03-08 13:57:58
    任务管理器每次手动修改优先级太麻烦了,如图: 2.可以用vbs脚本自动锁定程序优先级(适用于不同版本的windows): strComputer = "." tempName="" Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=...
  • 当我们在执行多个作业时,其实每个作业都会进入到CPU的任务分配中,等待CPU来执行,而CPU会根据每个作业的优先级(priority)来判断谁比较重要,所以有的作业就会优先执行。Linux系统中,每个进程都会拥有一个“优先级...
  • 在第3章中,他介绍了一种时间管理技术,该技术涉及列出任务并确定其优先级,以便能够快速完成生活中最重要的事情。根据最重要的因素,其本质上是生活。 我已经修改了象限,使其能够满足您的“比较” /“优先”需求,...
  • 本章节主要为大家讲解ThreadX任务优先级设置的注意事项、任务优先级的分配方案及其相关的一个例子,内容相对比较简单。 目录 12.1 任务优先级说明 12.2 任务优先级分配方案 12.3 中断优先级任务优先级区别 ...
  • 文章目录Hadoop 配置多队列的容量调度1 配置多队列的容量调度1.1 在 capacity-scheduler.xml...需求 2:配置队列优先级 1 配置多队列的容量调度 1.1 在 capacity-scheduler.xml 中配置如下 修改 <!-- 指定多
  • uCOS-II任务管理之改变任务的优先级

    千次阅读 2016-12-01 21:46:01
    uCOS-II任务管理之改变任务的优先级 在uCOS-II 里,任务的优先级也是是可以修改的。优先级翻转问题是可以通过改变任务优先级解决。 那什么是优先级翻转问题呢? 所谓优先级翻转问题(priority inversion)即当一个...
  • uCOS-II任务管理之改变任务的优先级 在uCOS-II 里,任务的优先级也是是可以修改的。优先级翻转问题是可以通过改变任务优先级解决。 那什么是优先级翻转问题呢? 所谓优先级翻转问题(priority inversion)即当一个高...
  • 日常任务优先级管理

    千次阅读 2016-07-12 15:32:39
    作为一个开发人员,我们经常会接到一堆开发任务,这些任务常常表现的都很急,都需要尽快完成。但是我们精力是有限的,也不能像CPU那样并发执行任务任务再多也只能一件一件的去做。那么,怎么对这些任务排序呢?...
  • react 优先级策略

    2022-03-17 20:31:07
    React内部对于优先级管理, 根据功能的不同分 LanePriority SchedulerPriority ReactPriorityLevel LanePriority fiber优先级(LanePriority): 位于react-reconciler包, 也就是基于Lane(车道模型). export const ...
  • FreeRTOS 任务优先级问题

    万次阅读 多人点赞 2017-10-11 17:45:08
    任务优先级说明
  • Windows任务管理器参数解释

    千次阅读 2019-06-05 18:04:55
    Windows任务管理器参数解释 一、概述及菜单  任务管理器提供正在您的计算上运行的程序和进程的相关信息。也显示最常用的度量进程性能的单位。 使用任务管理器可以监视计算机性能的关键指示。可以查看正在...
  • Java/Android中的优先级任务队列的实践

    万次阅读 多人点赞 2017-05-12 22:18:32
    本篇文章适用于Java和Android开发者,会从实现一个最简单的队列过渡到实现一个带有优先级的队列,使用生活中最常见的的例子结合讲解,保准你可以掌握基本的队列原理。
  • 文章目录资源管理资源是什么CPU的含义内存的含义请求和约束带资源请求的 Pod 如何调度和运行kubernetes资源对象请求(requests)上限(limits)默认资源配置(limit range)资源配额(resource quota)应用优先级QoS...
  • 进程管理ps,优先级,top命令

    千次阅读 2019-01-16 20:46:50
    进程管理ps,优先级,top命令 一、什么是进程 进程就是系统未完成并且正在进行的工作 二、查看进程 1)图片查看 gnome-system-monitor 2)ps命令 ps 1. a ##在当前环境中运行的进程 -A ##所有进程 f #...
  • 文章目录零、本讲学习目标二、线程管理(一)线程与消息处理1、主线程2、为什么需要多线程?(二)线程管理框架 - TaskDispatcher三、数据管理 零、本讲学习目标 掌握如何进行线程管理和消息处理 熟悉...
  • 优先级-创建与计划配置~
  • Linux任务管理器介绍

    千次阅读 2018-09-25 14:48:28
    第一行是任务队列信息,同uptime命令的执行结果。 eg. top - 15:09:51 up 17 days , 3:38 , 4 users , load average : 1.09 , 3.39 , 4.76 15:09:51 当前时间 up 17 days , 3:38 系...
  • Android优雅实现弹窗优先级管理

    千次阅读 2020-09-07 09:46:22
    前言 在日常的android开发中,我们...弹窗任务只是展示一些内容,如文本、图片等信息,可能还要有点击事件等,如果对UI要求不是很严格,那么可以使用系统提供的AlertDialog,这里简单写个示范: AlertDialog.Builder b
  • 项目为SSM框架,Web界面可以下发生产订单任务,订单任务可以设置优先级,后台由Control层接收请求后,由任务管理业务层通过RabbitMq发送消息到生产系统,实现是通过优先级队列完成,后期由于新增需求,处于等待中...
  • Linux下的任务管理器 top命令

    千次阅读 2018-11-06 06:18:15
    Linux下的任务管理器 top命令
  • 首先需要说明,我们常说的进程调度是传统的说法,但是实际上进程是资源管理的单位,线程才是调度的单位.有时也会说任务调度等。 linux的调度机制由调度策略(policies)和优先级(priority)两个属性共同决定.其中调度...
  • 在不改变优先级的情况下,编译运行程序,程序在电脑上默认的优先级是正常。...1、打开任务管理器->选中详细信息->右击你的程序->查看优先级 2、运行了上面的代码,程序优先级从默认正常变成高。则修改成功
  • 查看和设置进程优先级

    千次阅读 2021-08-06 17:02:37
    打开任务管理器,点击“详细信息”,选中要查看的exe,然后右键点击,在弹出的菜单中可以看到当前进程的优先级。 2.设置进程优先级 每个进程都有相应的优先级优先级决定它何时运行和占用 CPU 时间。进程...
  • 线程优先级7. 优先级编程7.1 进程7.2 线程8. 动态提升线程优先级 抢占式操作系统必须使用某种算法确定对何时应对哪些线程进行调度,时间又为多长。 1. 线程的挂起和恢复 在线程内核对象中有一个值表示线程的挂起...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 123,843
精华内容 49,537
热门标签
关键字:

任务管理器改优先级