vxWorks多任务编程初探-上

        进程(Process)是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。程序只是一组指令的有序集合,它本身没有任何运行的含义,只是一个静态实体。而进程则不同,它是程序在某个数据集上的执行,是一个动态实体。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消,反映了一个程序在一定的数据集上运行的全部动态过程。

        线程(Thread)是进程的一个实体,是CPU调度和分派的基本单位。线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

       线程和进程的关系是:线程是属于进程的,线程运行在进程空间内,同一进程所产生的线程共享同一内存空间,当进程退出时该进程所产生的线程都会被强制退出并清除。线程可与属于同一进程的其它线程共享进程所拥有的全部资源,但是其本身基本上不拥有系统资源,只拥有一点在运行中必不可少的信息(如程序计数器、一组寄存器和栈)。

       根据进程与线程的设置,操作系统大致分为如下类型:

           1、单进程、单线程:MS-DOS大致是这种操作系统;

           2、多进程、单线程:多数UNIX(及类Unix的Linux)是这种操作系统;

           3、多进程、多线程:Windows NT(以及基于NT内核的Windows 2000、XP等)、Solaris 2.x和OS/2都是这种操作系统;

           4、单进程、多线程:vxWorks就是这种操作系统。vxWorks只有一个进程(内存空间和资源分配),其任务的概念与线程大致相当,所有任务之间共享内存和其它资源。

        vxWorks由一个体积很小的内核及一些可以根据需要进行定制的系统模块组成。vxWorks 内核最小为 8KB,即便加上其它必要模块,所占用的空间也很小,且不失其实时、多任务的系统特征。vxWorks的内核主要包括:

        1、多任务:为满足真实世界事件的异步性,现代操作系统需提供多任务支持,由系统内核分配CPU给多个任务并发执行。如果是单CPU,则执行方式实质是宏观并行、微观串行;

        2、任务调度:真实世界的事件具有继承的优先级,当一个高优先级的任务变为可执行态,它会立即抢占当前正在运行的较低优先级的任务,vxWorks对这种优先级抢占调度(Preemptive Priority Scheduling)提供了支持。同时,vxWorks也支持同优先级任务间的时间片轮转调度(Round-Robin Scheduling);

        3、任务间的通讯与同步:在一个实时系统中,系统必须提供多个任务间快速且功能强大的通信机制,并提供为了有效地共享不可抢占的资源或临界区所需的同步机制;

       4、任务与中断之间的通信:许多外设以中断方式与CPU通信,我们不宜在中断服务程序(ISR)中进行过多的处理,通常将相应处理交给特定任务去完成。

相关的具体解释如下:

       硬件中断处理,硬件产生中断,统治系统调用相应的中断历程(ISR),位是系统得到尽快的响应,ISR在它自己独立的上下文和堆栈中运行,它的优先级高于任何任务优先级。

       中断延迟(Interrupt Latency),中断延迟是指从硬件中断发生到开始执行中断处理程序第一条指令之间的这段时间。

      优先级驱动(Priority-Driven),优先级驱动是指多任务系统中,当前运行任务总是具有最高优先级的就绪任务。

        多任务调度分为两种方式:优先抢占和轮转调度(Preemptive Priority,Round-Robin Scheduling)。优先抢占(Preemptive Priority):每一个任务都有一个优先级,系统核心保证优先级最高的任务运行于CPU。如果有任务优先级高于当前的任务优先级,系统立刻保存当前任务的上下文,切换到优先级高的上下文;抢占(Preemptive):抢占是指当系统处于核心态运行时,允许任务的重新调度。换句话说就是指正在执行的任务可以被打断,让另一个任务运行。抢占提高了应用对异步事件的响应性能力。操作系统内核可抢占,并不是说任务调度在任何时候都可以发生。例如当一个任务正在通过一个系统调用访问共享数据时,重新调度和中断都被禁止。

       任务上下文(Task Context):任务上下文是指任务运行的环境。例如,针对x86的CPU,任务上下文可包括程序计数器、堆栈指针、通用寄存器的内容。

       上下文切换(Context Switching):多任务系统中,上下文切换是指CPU的控制权由运行任务转移到另外一个就绪任务时所发生的事件,当前运行任务转为就绪(或者挂起、删除)状态,另一个被选定的就绪任务成为当前任务。上下文切换包括保存当前任务的运行环境,恢复将要运行任务的运行环境。上下文的内容依赖于具体的CPU。

       轮转调度(Round-Robin Scheduling):使所有相同优先级,状态为ready的任务公平分享CPU(分配一定的时间间隔,使个任务轮流享有CPU)。系统由256个优先级,从0到255,0为最高,255为最低. 任务在被创建时设定了优先级.也可用taskPrioritySet ( ) 来改变任务优先级。

任务的主要状态包括READY,PEND,DELAY,SUSPEND,各状态轮转如下:

ready-------->pended -----------semTake()/msgQReceive()-其他任务
  ready-------->delayed-----------taskDelay()
  ready-------->suspended---------taskSuspend()
  pended------->ready-------------semaGive()/msgQSend()-其他任务
  pended------->suspended---------taskSuspend()
  delayed------>ready-------------expired delay
  delayed------>suspended---------taskSuspend()
  suspended---->ready-------------taskResume()/taskActivate()
  suspended---->pended------------taskResume()
  suspended---->delayed-----------taskResume()
   轮转调度 (Round-Robin):轮转调度可以扩充到优先抢占方式中,当多个任务优先级相同的情况下,轮转调度算法使任务按平等的时间片运行于CPU,共享CPU.避免一个任务长时间占用 CPU,而导致其他任务不能运行.可以用 kernelTimeSlice() 来定义时间长度.taskLock ( )和 taskUnlock ( ) 用来取消优先抢占方式和恢复优先抢占方式.注意: 一个任务可以调用taskDelete ( ) 删除另一个任务,但是如果一个当前正在运行的任务被删除后,该任务的内存没有释放,而其他任务不知道,依然在等待,结果导致系统stop.用 taskSafe ( ) 和 taskUnsafe ( ) 来保证正在运行的任务不被删除.用法如下:

[cpp] view plaincopy
  1.  taskSafe ();   
  2. semTake (semId, WAIT_FOREVER);   
  3.  .. .critical region .   
  4. semGive (semId);semGive (semId);   
  5. taskUnsafe ();   
  6. . .critical region .   
  7. semGive (semId);semGive (semId);   
  8. taskUnsafe ();   

tasklock()和和 taskUnlock()用来取消优先抢占方式和恢复优先抢占方式。

下面介绍下任务间的同步和进程间协调:

信号量作为任务间同步和互斥的机制。在 wind 核中有几种类型的信号量,它们分别针对不同的应用需求:二进制信号量、计数信号量、互斥信号量和 POSIX 信号量。所有的这些信号量是快速和高效的,它们除了被应用在开发设计过程中外,还被广泛地应用在VxWorks 高层应用系统中。对于进程间通信,wind 核也提供了诸如消息队列、管道、套接字和信号等机制。
任务间的同步和进程间协调的几种方式:
  内存共享(Shared Memory),对简单的数据共享而言.
  信号量(Semaphore),基本的互斥和同步.
  消息队列(Message queues)和管道(Pipe),单个CPU中,任务间的信息传递.
  套结字(Socket)和远程调用(Remote procedure calls),相对于网络任务间的通信.
  信号(Signals),出错处理(Exception handling).
   内存共享(Shared Memory)
任务间通信最通常的方式是通过共享的数据结构进行通信,因为所有VxWorks的任务存在于一个单一的线性地址空间,任务间共享数据。全局变量、线性队列、环形队列、链表、指针都可被运行在不同上下文的代码所指向。
互斥(Mutual Exclusion)
  互斥是用来控制多任务对共享数据进行串行访问的同步机制。在多任务应用中,当两个或多个任务同时访问共享数据时,可能会造成数据破坏。互斥使它们串行地访问数据,从而达到保护数据的目的.
  解决互斥的几种方法:
1. 关闭中断的方法(intLock): 能解决任务和中断ISR之间产生的互斥.

[cpp] view plaincopy
  1. funcA ()   
  2. int lock = intLock();   
  3. . . critical region that cannot be interrupted .   
  4. intUnlock (lock); }   

  但在实时系统中采取这个办法会影响系统对外部中断及时响应和处理的能力.
2. 关闭系统优先级(taskLock): 关闭系统优先级,这样在当前任务执行时,除了中断外,不会有其他优先级高的任务来抢占CPU,影响当前程序运行.

[cpp] view plaincopy
  1. funcA () { taskLock ();   
  2. . . critical region that cannot be interrupted .   
  3. taskUnlock (); }   

这种方法阻止了高优先级的任务抢先运行,在实时系统中也是不适合的,除非关闭优先级的时间特别短.

信号量(Semaphore): 信号量是解决互斥和同步协调进程最好的方法。VxWorks信号量提供最快速的任务间通信机制,它主要用于解决任务间的互斥和同步。针对不同类型的问题,有以下三种信号量:
  1、二进制信号量(binary) 使用最快捷、最广泛,主要用于同步或互斥;
  2、互斥信号量(mutual exclusion) 特殊的二进制信号量,主要用于优先级继承、安全删除和回溯;
  3、计数器信号量(counting) 和二进制信号量类似,保持信号量被释放(gaven)的次数。主要用于保护一个资源的多个例程(multiple instances of a resource)

信号量控制,函数介绍:
  semBCreate( ) 分配并初始化一个二进制信号量
  semMCreate( ) 分配并初始化一个互斥信号量
  semCCreate( ) 分配并初始化一个计数信号量
  semDelete( ) 终止一个自由的信号量
  emTake( ) 占有一个信号量
  semGive( ) 释放一个信号量
  semFlush( ) 解锁所有等待信号量的任务
semBCreate( ), semMCreate( ), and semCCreate( )返回一个信号量ID作为其它后续任务使用该信号量的的句柄。当一个信号量被创建,它的队列(queue)类型就被确定。等待信号量的任务队列以优先级的高低排列(SEM_Q_PRIORITY),或者一先到先得的方式排列(SEM_Q_FIFO).
当一个Semaphore创建时,指定了任务队列的种类。

semBCreat( SEM_Q_PRIORITY, SEM_FULL), SEM_Q_PRIORITY 指明处于等待状态的任务在等待队列中以优先级的顺序排列
  semBCreat(SEM_Q_FIFO,SEM_FULL), SEM_Q_FIFO指明处于等待状态的任务在等待队列中以先进先出的顺序排列
互斥进程(Mutual Exclusion)
  互斥信号量有效的内锁对共享资源的进入,与屏蔽中断(disabling interrupts)和优先级锁定(preemptive locks)相比,二进制信号量将互斥的范围限制在仅与其有关的资源上。从技术上说,创建一个信号量来保护(guarding)资源。信号量初始化位可用的(FULL),当一个Semaphore创建时,指定了这个semaphore是用在解决互斥还是用来同步任务

semBCreat( SEM_Q_FIFO, SEM_FULL) , SEM_FULL 指明用于任务间互斥.
  SEM_ID semMutex;semMutex = semBCreate (SEM_Q_PRIORITY, SEM_FULL)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/255431.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【pyqt5学习】——重写窗口右上角关闭事件closeEvent()

目录 1、法一:设置中文按钮 2、法二:不设置中文按钮 pyqt5 关闭按钮显示提示信息_Marvin_Xavier的博客-CSDN博客_pyqt 关闭按钮https://blog.csdn.net/marwenx/article/details/107226531 1、法一:设置中文按钮 def closeEvent(self, even…

感动要哭 撸了一个半小时的重载预算符高精

撸了一个半小时代码,没玩守望(垃圾游戏毁我青春五个金牌都带不起队友)最后编译出312个错误。吓我,然而改了几个地方就直接过了直接过了直接过了,目前还是不明白ostream,istream的用处,上网才搞定…

LVDS DP等显示器接口简介

LVDS 产品传输速率从几百Mbps到2Gbps。它是电流驱动的,他通过在接收端放置一个负载而得到的电压,当电流正向流动,接收端输出为1,反之为0,它的摆幅250mV-450mV. lvds 即低压差分信号传输,是一种满足高性能传…

http协议相关内容

二、HTTP协议1、协议:共同遵守的规则。2、网络协议有:TCP(有三次握手机制)/IP:传输控制协议/地址协议,SMTP:简单邮件传输协议,FTP:文件传输协议,http&#xf…

使用XmlTextReader 读取XML

XmlTextReader 限于只向前的读取 XmlTextReader 的技术类似于读取其他任何文件 首先打开文件,然后从文件中读取信息,最后关闭文件. 每次从文件中读取信息时,他在文件中的位置都会前移.到达文件结尾的时候就什么都不读了。 1 创建XmlTextReader对象 …

C#中ComboBox动态绑定赋值

http://www.crifan.com/csharp_combobox_data_dynamic_binding/ C#中,已有一个List,想要动态的,绑定到ComboBox中。 【解决过程】 1.参考: c# winform comboBox动态绑定数据 去试试代码: cmbSubCategory.DataSource g…

【pyqt5学习】——日历控件calendarWidget设置单元格格式(前景、背景)、日历控件属性编辑

目录 0、导入库 1、返回日历选中的日期 2、更改日历控件周几(比如一个月属于周一的日期)的所有格子属性 3、更改日历控件单个格子(指定日期)属性 4、日历格子属性 5、信号——clicked() 6、成果展示 0、导入库 from PyQt5.Q…

linux内核数据结构之链表

1、前言 最近写代码需用到链表结构,正好公共库有关于链表的。第一眼看时,觉得有点新鲜,和我之前见到的链表结构不一样,只有前驱和后继指针,而没有数据域。后来看代码注释发现该代码来自linux内核,在linux源…

为什么使用 XML

为什么使用 XML? Web 使我们能够与任何地方的任何人通讯。广泛接受的标准(这对完全使用 Web 的潜力是至关重要的)允许 Web 在多种交互操作的技术层上通讯。一个重要层是可视化显示和用户界面,例如 HTML、GIF 和 JScript(TM) 之类的…

bzoj1084: [SCOI2005]最大子矩阵

dp。转移方程在代码里。。转载于:https://www.cnblogs.com/invoid/p/5451202.html

ci事务

参考链接:http://www.tuicool.com/articles/jqeuU3转载于:https://www.cnblogs.com/norm/p/6382396.html

【bug修复】you must feed a value for placeholder tensor ‘Placeholder‘ with dtype float解决方案

最近碰到了这个you must feed a value for placeholder tensor Placeholder with dtype float and shape的问题,字面意思很好理解,就是没有给Placeholder赋值,可是我明明赋值了,百度了许多,也都是让我检查是否赋值以及…

动态代理3之代理工厂实现

动态代理的深化:承接动态代理2( 对 上级实例进行 深化),也就是 spring 的前身 (必须掌握)实例: 文件说明:1.有一个Waiter接口,该接口有一个 server() 、ShouQian()方法 2.有一个 Waiter接口的实…

一个简单的XML文档例子

一个简单的XML文档例子: <?xml version"1.0"?> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Dont forget me this weekend!</body> </note> 文档的第一…

python set

python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和sysmmetric difference(对称差集)等数学运算. sets 支持 x in set, len(set),和 for x in set。作为一个无序的集…

【bug修复】解决ValueError: Tensor(“Variable:0“ dtype=float32_ref) must be from the same graph as Tensor(“R

bug:描述 在进行tensorflow进行搭建CNN网络时&#xff0c;在定义CNN的py文件中调用cnn模型&#xff0c;运行正常&#xff0c;但是在其他py文件中进行时就出现问题 ValueError: Tensor(“Variable:0” dtypefloat32_ref) must be from the same graph as Tensor(“Reshape:0”,…

XML —— DTD介绍

一、DTD介绍 Document Type Definition&#xff1b; DTD是一种XML的约束方式&#xff0c;除了此种约束方式外&#xff0c;还有XSchema&#xff0c;XSchema比DTD的约束能力还要强&#xff0c;因此DTD正在逐渐淘汰&#xff1b; DTD的目的就是约束XML标签的写法&#xff1b;比如在…

error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

更新的软件可以解决 TortoiseGit-preview-2.5.7.0-20180127-b2d00f8-64bit.msi和Git-2.16.2-64-bit.exe。 链接地址为&#xff1a; https://github.com/git-for-windows/git/releases/download/v2.16.2.windows.1/Git-2.16.2-64-bit.exe https://download.tortoisegit.org/tgi…

Linux 图片传输功能c/c++(初版)

由于深度学习任务的需要&#xff0c;要在程序里面嵌入一个module。 这个module 的功能是接收来自ios客户端的图片。并且传送给深度学习分类器进行处理。 于是看了看各种各样的 module 实现方案。 先是用IO函数把图片以数组的方式存起来。 再和服务器建立连接&#xff0c;socket…

Val编程-val系列编程思想

利用Val语言可以编写出各种各样的应用程序。正如windows phone面临的窘境一样&#xff0c;受众太小&#xff0c;市场不大。应用程序不多&#xff0c;所以也谈不上成熟。国内的应用程序基本上就是简单的小程序&#xff0c;谈不上什么编程思想。国外许多都是基于kernel的而衍生出…