第8章 互斥信号量管理

合集下载

信号量、互斥量、同步变量、条件变量和事件变量

信号量、互斥量、同步变量、条件变量和事件变量

信号量、互斥量、同步变量、条件变量和事件变量信号量:信号量(Semaphore),有时被称为信号灯,是在多线程环境下使⽤的⼀种设施,是可以⽤来保证两个或多个关键代码段不被调⽤。

在进⼊⼀个关键代码段之前,线程必须获取⼀个信号量;⼀旦该关键代码段完成了,那么该线程必须释放信号量。

其它想进⼊该关键代码段的线程必须等待直到第⼀个线程释放信号量。

为了完成这个过程,需要创建⼀个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的⾸末端。

确认这些信号量VI引⽤的是初始创建的信号量。

互斥量:互斥量是⼀个可以处于两态之⼀的变量:解锁和加锁。

这样,只需要⼀个位表⽰它,不过实际上,常常使⽤⼀个,0表⽰解锁,⽽其他所有的值则表⽰加锁。

互斥量使⽤两个过程。

当⼀个(或进程)需要访问时,它调⽤mutex_lock。

如果该互斥量当前是解锁的(即临界区可⽤),此调⽤成功,调⽤线程可以⾃由进⼊该临界区。

另⼀⽅⾯,如果该互斥量已经加锁,调⽤线程被阻塞,直到在临界区中的线程完成并调⽤mutex_unlock。

如果多个线程被阻塞在该互斥量上,将随机选择⼀个线程并允许它获得锁。

同步变量:条件变量:事件变量:四种进程或线程同步互斥的控制⽅法1、临界区:通过对多线程的串⾏化来访问公共资源或⼀段代码,速度快,适合控制数据访问。

2、互斥量:为协调共同对⼀个共享资源的单独访问⽽设计的。

3、信号量:为控制⼀个具有有限数量⽤户资源⽽设计。

4、事件:⽤来通知线程有⼀些事件已发⽣,从⽽启动后继任务的开始。

临界区(Critical Section)保证在某⼀时刻只有⼀个线程能访问数据的简便办法。

在任意时刻只允许⼀个线程对共享资源进⾏访问。

如果有多个线程试图同时访问临界区,那么在有⼀个线程进⼊后其他所有试图访问此临界区的线程将被挂起,并⼀直持续到进⼊临界区的线程离开。

临界区在被释放后,其他线程可以继续抢占,并以此达到⽤原⼦⽅式操作共享资源的⽬的。

互斥量和信号量

互斥量和信号量

互斥量和信号量1. 什么是互斥量和信号量?1.1 互斥量(Mutex)互斥量是一种同步原语,用于控制对共享资源的访问。

它允许多个线程或进程并发执行,但是只有一个线程或进程可以同时访问共享资源。

当一个线程或进程要访问共享资源时,它必须先获得互斥量的所有权,其他线程或进程必须等待。

互斥量有两种状态:锁定和解锁。

当一个线程或进程获得互斥量的所有权时,它将互斥量锁定,并且其他线程或进程无法获得该互斥量的所有权。

只有当持有互斥量的线程或进程释放了该互斥量后,其他线程或进程才能获取到该互斥量的所有权。

1.2 信号量(Semaphore)信号量也是一种同步原语,用于控制对共享资源的访问。

与互斥量不同的是,信号量可以允许多个线程或进程同时访问共享资源。

信号量有一个计数器和一个等待队列。

当一个线程或进程要访问共享资源时,它必须先尝试获取信号量的所有权。

如果信号量的计数器大于零,线程或进程将获得信号量的所有权并继续执行。

如果信号量的计数器等于零,线程或进程将被阻塞并加入到等待队列中。

当持有信号量的线程或进程释放了该信号量后,等待队列中的一个线程或进程将被唤醒,并获得信号量的所有权。

这样就实现了多个线程或进程同时访问共享资源的控制。

2. 互斥量和信号量的应用场景2.1 互斥量的应用场景互斥量常用于以下情况:•多个线程需要访问共享资源,但是只能有一个线程能够访问。

•防止竞态条件(Race Condition)发生,保证共享资源在同一时间只被一个线程访问。

•在多线程编程中实现临界区(Critical Section)。

2.2 信号量的应用场景信号量常用于以下情况:•控制对有限资源(如数据库连接、文件句柄等)的并发访问。

•控制对共享数据结构(如缓冲区、队列等)的并发操作。

•控制对临界区(Critical Section)的并发访问。

3. 互斥量和信号量的实现方式3.1 互斥量的实现方式互斥量的实现方式有多种,常见的有以下几种:•基于硬件指令:一些处理器提供了硬件级别的原子操作指令,可以用来实现互斥量。

国家开放大学《操作系统》章节测试参考答案

国家开放大学《操作系统》章节测试参考答案

国家开放大学《操作系统》章节测试参考答案第1章操作系统概述一、单项选择题1.操作系统的基本职能是()。

A. 提供用户界面,方便用户使用B. 提供方便的可视化编辑程序C. 提供功能强大的网络管理工具D. 控制和管理系统内各种资源,有效地组织多道程序的运行2.按照所起的作用和需要的运行环境,操作系统属于()。

A. 应用软件B. 系统软件C. 支撑软件D. 用户软件3.在计算机系统中,操作系统是()。

A. 处于裸机之上的第一层软件B. 处于系统软件之上的用户软件C. 处于应用软件之上的系统软件D. 处于硬件之下的低层软件4.现代操作系统的基本特征是()、资源共享和操作的异步性。

A. 程序的并发执行B. 实现分时与实时处理C. 多道程序设计D. 中断处理5.以下不属于操作系统具备的主要功能的是()。

A. 中断处理B. CPU调度C. 内存管理D. 文档编辑6.为用户分配主存空间,保护主存中的程序和数据不被破坏,提高主存空间的利用率。

这属于()。

A. 存储管理B. 作业管理C. 文件管理D. 处理器管理7.操作系统对缓冲区的管理属于()的功能。

A. 设备管理B. 存储器管理C. 文件管理D. 处理器管理8.操作系统内核与用户程序、应用程序之间的接口是()。

A. shell命令B. C语言函数C. 图形界面D. 系统调用9.系统调用是由操作系统提供的内部调用,它()。

A. 与系统的命令一样B. 直接通过键盘交互方式使用C. 是命令接口中的命令D. 只能通过用户程序间接使用10.在下列操作系统中,强调吞吐能力的是()。

A. 多道批处理系统B. 实时系统C. 网络系统D. 分时系统11.批处理系统的主要缺点是()。

A. CPU的利用率不高B. 系统吞吐量小C. 不具备并行性D. 失去了交互性12.为了使系统中所有的用户都能得到及时的响应,该操作系统应该是()。

A. 分时系统B. 网络系统C. 实时系统D. 多道批处理系统13.下面不属于分时系统特征的是()。

ucosii 互斥信号量 创建条件

ucosii 互斥信号量 创建条件

ucosii 互斥信号量创建条件摘要:1.ucosii 简介2.互斥信号量的概念3.互斥信号量的创建条件4.互斥信号量在ucosii 中的应用正文:【1.ucosii 简介】ucosii是一款基于μC/OS-II实时操作系统的嵌入式软件开发平台。

μC/OS-II是一个源代码公开的实时操作系统内核,其主要特点是可移植性强、占用资源少、实时性能优越,适用于各种嵌入式系统。

ucosii在μC/OS-II的基础上,提供了丰富的组件和工具,便于开发者快速构建嵌入式系统。

【2.互斥信号量的概念】互斥信号量(Mutex)是一种同步原语,用于实现多任务之间的互斥访问。

互斥信号量有一个计数器,用于表示当前有多少任务正在访问共享资源。

当一个任务要访问共享资源时,需要先请求互斥信号量。

如果计数器为零,表示当前没有其他任务访问共享资源,请求信号量后计数器加一,任务可以访问共享资源;如果计数器大于零,表示其他任务正在访问共享资源,请求信号量后计数器加一,任务需要等待其他任务访问完成后才能访问共享资源。

任务访问完共享资源后,释放互斥信号量,计数器减一,表示可以有其他任务访问共享资源。

【3.互斥信号量的创建条件】在ucosii 中,创建互斥信号量需要满足以下条件:1.互斥信号量对象需要分配在用户空间,不能分配在内核空间。

2.互斥信号量对象的初始化需要保证计数器为零,表示没有任务访问共享资源。

3.互斥信号量对象需要关联一个等待队列,用于存放等待访问共享资源的任务。

【4.互斥信号量在ucosii 中的应用】在ucosii 中,互斥信号量可以用于保护共享资源,避免多任务同时访问导致的数据不一致问题。

以下是一个简单的互斥信号量使用示例:```c#include "ucosii.h"#include "ucosii_os.h"// 定义共享资源int32_t g_data;// 创建互斥信号量MUTEX_T g_mutex;// 初始化互斥信号量void init_mutex() {mutex_init(&g_mutex, 0);}// 访问共享资源void access_data() {int32_t i;for (i = 0; i < 10; i++) {// 获取互斥信号量mutex_lock(&g_mutex);// 访问共享资源g_data = i;// 释放互斥信号量mutex_unlock(&g_mutex);}}// 任务入口void app_main() {init_mutex();// 启动多个任务访问共享资源while (1) {task_create(1, access_data, NULL);}}```在这个示例中,我们定义了一个共享资源g_data,并创建了一个互斥信号量g_mutex。

互斥信号量实现的功能

互斥信号量实现的功能

互斥信号量实现的功能互斥信号量是操作系统中常用的同步机制之一,它可以用来控制多个线程或进程之间对共享资源的访问。

本文将从以下几个方面详细介绍互斥信号量实现的功能。

一、互斥信号量的概念互斥信号量是一种二元信号量,它只有两种状态:0和1。

当一个线程或进程获得了互斥信号量后,其他线程或进程就不能再获得该信号量,只有等待该线程或进程释放该信号量后才能再次竞争。

二、实现原理互斥信号量的实现原理基于操作系统提供的原子操作(Atomic Operation),即在执行过程中不会被其他线程或进程干扰的操作。

在使用互斥信号量时,需要使用操作系统提供的特定函数来获取和释放该信号量,并且这些函数都是原子操作。

三、应用场景1. 线程同步在多线程编程中,通常需要对共享资源进行同步访问。

如果没有同步机制,可能会导致数据竞争等问题。

使用互斥信号量可以避免这些问题,确保每个线程都能按照规定顺序访问共享资源。

2. 进程同步在多进程编程中,不同进程之间也可能需要对共享资源进行同步访问。

使用互斥信号量可以确保每个进程都能按照规定顺序访问共享资源,避免数据竞争等问题。

3. 临界区保护在程序中,临界区是指一段代码,在该代码段中对共享资源进行读写操作。

使用互斥信号量可以将临界区保护起来,确保每次只有一个线程或进程能够访问该代码段。

4. 避免死锁在多线程或多进程编程中,如果没有良好的同步机制,可能会导致死锁问题。

使用互斥信号量可以避免这些问题,并确保程序的正常运行。

四、实现方法1. P操作(Wait)P操作用于获取互斥信号量,在获取之前需要检查该信号量是否为1。

如果为1,则将其减1并继续执行;如果为0,则阻塞当前线程或进程直到该信号量被释放。

2. V操作(Signal)V操作用于释放互斥信号量,在释放之前需要将其加1。

如果有其他线程或进程正在等待该信号量,则唤醒其中一个线程或进程以获取该信号量。

五、优缺点分析优点:1. 可以避免数据竞争等问题,确保程序的正确性。

互斥信号量的作用

互斥信号量的作用

互斥信号量的作用
嘿,朋友们!今天咱来聊聊互斥信号量这个玩意儿。

你说这互斥信号量啊,就像是一个特别厉害的交通指挥员。

就好比说有一群小伙伴要去抢一个玩具,要是没有个规矩,那肯定乱套啦。

这时候互斥信号量就站出来了,它说:“嘿,都别抢,一个一个来!”
有一次啊,我就看到小王和小李在那为了争一本书差点打起来了。

我就跟他们说:“哎呀,你们别闹啦,要是有个互斥信号量在这就好啦!”小王就问:“啥是互斥信号量啊?”我就解释说:“你看啊,就像这本书,你们不能同时去抢,得一个人先看,另一个人等他看完了再看,这互斥信号量就是管这个顺序的。


小李恍然大悟:“哦,原来是这样啊,那要是没有这个互斥信号量,不就乱套了嘛。

”我说:“对啊,所以它很重要呢。


再比如说排队买东西也是一样的道理呀。

大家都要按顺序来,不能乱插队。

这互斥信号量就确保了这个秩序。

你想想,要是程序里面的多个进程都想去访问同一个资源,没有互斥信号量的话,那不是乱成一锅粥啦。

它就像是一道屏障,把那些可能会产生混乱的操作给隔开了,让一切都变得井井有条。

有时候我就想啊,我们的生活中其实也有很多类似互斥信号量的东西呢。

比如说十字路口的红绿灯,它就是在协调不同方向的车辆和行人,让大家有序地通过。

还有在一些公共场合,大家要遵守的规则,其实也起到了互斥信号量的作用。

总之呢,互斥信号量就是让事情变得有秩序,避免混乱和冲突。

它虽然看不见摸不着,但在程序的世界里可是发挥着大作用呢!它让那些进程们都能乖乖地按照规则来,谁也别想乱来。

所以啊,可别小瞧了这互斥信号量哦,它真的很重要!。

互斥信号量取值范围

互斥信号量取值范围

互斥信号量取值范围互斥信号量是操作系统中常用的同步机制之一,用于控制对共享资源的访问,保证在任意时刻只有一个进程或线程可以访问该资源。

互斥信号量的取值范围是一个整数,其取值通常为非负整数。

在操作系统中,互斥信号量通常用来解决多个进程或线程访问共享资源时的争用问题。

当一个进程或线程需要访问共享资源时,它会尝试对互斥信号量进行P操作(原语操作),如果互斥信号量的值大于0,则该进程或线程可以访问共享资源,并将互斥信号量的值减1;如果互斥信号量的值等于0,则该进程或线程需要等待,直到互斥信号量的值大于0才能继续执行。

互斥信号量的取值范围通常是在操作系统中预定义的,其最小值为0,表示共享资源已被占用;而最大值则取决于操作系统的设计和实现。

在一些操作系统中,互斥信号量的取值范围可以是任意的整数,而在其他操作系统中,互斥信号量的取值范围可能会受到一定限制。

互斥信号量的取值范围的大小直接影响了系统的并发性能和可扩展性。

如果互斥信号量的取值范围过小,可能会导致系统频繁地进行阻塞和唤醒操作,增加了系统的开销;而如果互斥信号量的取值范围过大,可能会导致系统的资源浪费和性能下降。

因此,在设计和实现互斥信号量时,需要合理选择其取值范围,以保证系统的性能和可靠性。

除了互斥信号量的取值范围外,还有一些与互斥信号量相关的概念和属性也需要注意。

例如,互斥信号量通常具有两种状态:空闲状态和占用状态。

当互斥信号量的值为0时,表示共享资源已被占用;而当互斥信号量的值大于0时,表示共享资源是空闲的。

此外,互斥信号量还具有原子性和互斥性的特点,保证了对共享资源的访问是有序的和互斥的。

在实际应用中,互斥信号量的取值范围的选择需要根据系统的具体需求和性能要求来确定。

对于资源有限的系统,可以选择较小的取值范围,以提高系统的并发性能;而对于资源较为充足的系统,可以选择较大的取值范围,以提高系统的可扩展性和灵活性。

互斥信号量的取值范围是一个整数,通常为非负整数。

互斥信号量和二值信号量

互斥信号量和二值信号量

互斥信号量和二值信号量互斥信号量和二值信号量是计算机科学中常用的同步机制。

它们的作用是确保在多线程或多进程环境中,对共享资源的访问顺序和正确性。

本文将分别介绍互斥信号量和二值信号量的概念、原理和应用。

互斥信号量是一种特殊类型的信号量,它的值只能是0或1。

当互斥信号量的值为1时,表示共享资源未被占用,可以被访问;当互斥信号量的值为0时,表示共享资源已被占用,其他线程或进程需要等待。

互斥信号量的原理是通过对共享资源的访问进行加锁和解锁操作来实现同步。

当一个线程或进程要访问共享资源时,首先需要尝试将互斥信号量的值减1,如果成功,则表示资源未被占用,可以访问;如果失败,则表示资源已被占用,需要等待其他线程或进程释放资源。

互斥信号量的应用非常广泛。

在操作系统中,互斥信号量常被用于实现进程间的互斥访问和同步操作。

在多线程编程中,互斥信号量可以避免多个线程同时访问共享资源导致的数据竞争和不一致性。

例如,在一个多线程的银行账户系统中,多个线程同时对同一个账户进行存款或取款操作,就需要使用互斥信号量来确保只有一个线程能够访问账户并更新余额。

二值信号量与互斥信号量类似,也是一种特殊类型的信号量,它的值只能是0或1。

不同之处在于,二值信号量的值为0时,表示共享资源不可用;值为1时,表示共享资源可用。

二值信号量的原理和互斥信号量相似,通过加锁和解锁操作来实现对共享资源的同步访问。

当一个线程或进程需要访问共享资源时,首先需要尝试将二值信号量的值减1,如果成功,则表示资源可用,可以访问;如果失败,则表示资源不可用,需要等待其他线程或进程释放资源。

二值信号量的应用也非常广泛。

在操作系统中,二值信号量常被用于实现生产者-消费者模型。

生产者线程负责生产数据并将其放入一个共享缓冲区,消费者线程负责从缓冲区中取出数据进行消费。

为了避免生产者和消费者同时访问缓冲区导致的数据竞争和不一致性,可以使用一个二值信号量来控制对缓冲区的访问。

当缓冲区为空时,消费者需要等待生产者将数据放入缓冲区;当缓冲区已满时,生产者需要等待消费者将数据取出。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第8章互斥型信号量管理任务可以用互斥型信号量实现对共享资源的独占式处理。

mutex是二值信号量。

mutex可以在应用程序中用于降解优先级反转问题。

互斥型信号量由3个元素组成:1个标志,指示mutex是否可以使用(0或1);1个优先级,准备一旦高优先级的任务需要这个mutex,赋给占有mutex的任务;1个等待该mutex的任务列表。

对于互斥型信号量提供6种服务:OSMutexCreate(),OSMutexDel(),OSMutexPend(),OSMutexPost(),OSMutexAccept(),OSMutexQuery()。

mutex只能供任务使用,用于处理共享资源。

8.00 建立一个互斥型信号量, OSMutexCreate()程序清单 L8.2建立一个信号量OS_EVENT *OSMutexCreate (INT8U prio, INT8U *err){#if OS_CRITICAL_METHOD == 3OS_CPU_SR cpu_sr;#endifOS_EVENT *pevent;if (OSIntNesting > 0) {*err = OS_ERR_CREATE_ISR;return ((OS_EVENT *)0);}#if OS_ARG_CHK_EN > 0if (prio >= OS_LOWEST_PRIO) {*err = OS_PRIO_INVALID;return ((OS_EVENT *)0);}#endifOS_ENTER_CRITICAL();if (OSTCBPrioTbl[prio] != (OS_TCB *)0) {OS_EXIT_CRITICAL();*err = OS_PRIO_EXIST;return ((OS_EVENT *)0);}OSTCBPrioTbl[prio] = (OS_TCB *)1;pevent = OSEventFreeList;if (pevent == (OS_EVENT *)0) {OSTCBPrioTbl[prio] = (OS_TCB *)0;OS_EXIT_CRITICAL();*err = OS_ERR_PEVENT_NULL;return (pevent);}OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; OS_EXIT_CRITICAL();pevent->OSEventType = OS_EVENT_TYPE_MUTEX;pevent->OSEventCnt = (prio << 8) | OS_MUTEX_AVAILABLE;pevent->OSEventPtr = (void *)0;OS_EventWaitListInit(pevent);*err = OS_NO_ERR;return (pevent);}8.01 删除一个互斥型信号量, OSMutexDel()#if OS_MUTEX_DEL_ENOS_EVENT *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *err){#if OS_CRITICAL_METHOD == 3OS_CPU_SR cpu_sr;#endifBOOLEAN tasks_waiting;INT8U pip;if (OSIntNesting > 0) {*err = OS_ERR_DEL_ISR;return (pevent);}#if OS_ARG_CHK_EN > 0if (pevent == (OS_EVENT *)0) {*err = OS_ERR_PEVENT_NULL;return ((OS_EVENT *)0);}if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {*err = OS_ERR_EVENT_TYPE;return (pevent);}#endifOS_ENTER_CRITICAL();if (pevent->OSEventGrp != 0x00) {tasks_waiting = TRUE;} else {tasks_waiting = FALSE;}switch (opt) {case OS_DEL_NO_PEND:if (tasks_waiting == FALSE) {pip = (INT8U)(pevent->OSEventCnt >> 8); OSTCBPrioTbl[pip] = (OS_TCB *)0;pevent->OSEventType = OS_EVENT_TYPE_UNUSED;pevent->OSEventPtr = OSEventFreeList;OSEventFreeList = pevent;OS_EXIT_CRITICAL();*err = OS_NO_ERR;return ((OS_EVENT *)0);} else {OS_EXIT_CRITICAL();*err = OS_ERR_TASK_WAITING;return (pevent);}case OS_DEL_ALWAYS:while (pevent->OSEventGrp != 0x00) {OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX); }pip = (INT8U)(pevent->OSEventCnt >> 8); OSTCBPrioTbl[pip] = (OS_TCB *)0;pevent->OSEventType = OS_EVENT_TYPE_UNUSED;pevent->OSEventPtr = OSEventFreeList;OSEventFreeList = pevent;OS_EXIT_CRITICAL();if (tasks_waiting == TRUE) {OS_Sched();}*err = OS_NO_ERR;return ((OS_EVENT *)0);default:OS_EXIT_CRITICAL();*err = OS_ERR_INVALID_OPT;return (pevent);}}#endif8.02 等待一个互斥型信号量, OSSemPend()程序清单 L8.4 等待一个互斥型信号量void OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *err){#if OS_CRITICAL_METHOD == 3OS_CPU_SR cpu_sr;#endifINT8U pip;INT8U mprio;BOOLEAN rdy;OS_TCB *ptcb;if (OSIntNesting > 0) {*err = OS_ERR_PEND_ISR;return;}#if OS_ARG_CHK_EN > 0if (pevent == (OS_EVENT *)0) {*err = OS_ERR_PEVENT_NULL;return;}if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {*err = OS_ERR_EVENT_TYPE;return;}#endif (1) OS_ENTER_CRITICAL();if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) ==OS_MUTEX_AVAILABLE) {pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;pevent->OSEventCnt |= OSTCBCur->OSTCBPrio;pevent->OSEventPtr = (void *)OSTCBCur;OS_EXIT_CRITICAL();*err = OS_NO_ERR;return;}pip = (INT8U)(pevent->OSEventCnt >> 8);mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);ptcb = (OS_TCB *)(pevent->OSEventPtr);if (ptcb->OSTCBPrio != pip && mprio > OSTCBCur->OSTCBPrio) {if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) { if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {OSRdyGrp &= ~ptcb->OSTCBBitY;}rdy = TRUE;} else {rdy = FALSE;}ptcb->OSTCBPrio = pip;ptcb->OSTCBY = ptcb->OSTCBPrio >> 3;ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY];ptcb->OSTCBX = ptcb->OSTCBPrio & 0x07;ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX];if (rdy == TRUE) {OSRdyGrp |= ptcb->OSTCBBitY;OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;}OSTCBPrioTbl[pip] = (OS_TCB *)ptcb;}OSTCBCur->OSTCBStat |= OS_STAT_MUTEX; OSTCBCur->OSTCBDly = timeout; OS_EventTaskWait(pevent); OS_EXIT_CRITICAL();OS_Sched(); OS_ENTER_CRITICAL();if (OSTCBCur->OSTCBStat & OS_STAT_MUTEX) { OS_EventTO(pevent);OS_EXIT_CRITICAL();*err = OS_TIMEOUT; return;}OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;OS_EXIT_CRITICAL();*err = OS_NO_ERR;}8.03 释放一个互斥型信号量, OSMutexPost()INT8U OSMutexPost (OS_EVENT *pevent){#if OS_CRITICAL_METHOD == 3OS_CPU_SR cpu_sr;#endifINT8U pip;INT8U prio;if (OSIntNesting > 0) {return (OS_ERR_POST_ISR);}#if OS_ARG_CHK_EN > 0if (pevent == (OS_EVENT *)0) {return (OS_ERR_PEVENT_NULL);}if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) {return (OS_ERR_EVENT_TYPE);}#endifOS_ENTER_CRITICAL();pip = (INT8U)(pevent->OSEventCnt >> 8);prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);if (OSTCBCur->OSTCBPrio != pip &&OSTCBCur->OSTCBPrio != prio) { OS_EXIT_CRITICAL();return (OS_ERR_NOT_MUTEX_OWNER);}if (OSTCBCur->OSTCBPrio == pip) {if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) ==0){OSRdyGrp &= ~OSTCBCur->OSTCBBitY;}OSTCBCur->OSTCBPrio = prio;OSTCBCur->OSTCBY = prio >> 3;OSTCBCur->OSTCBBitY = OSMapTbl[OSTCBCur->OSTCBY];OSTCBCur->OSTCBX = prio & 0x07;OSTCBCur->OSTCBBitX = OSMapTbl[OSTCBCur->OSTCBX];OSRdyGrp |= OSTCBCur->OSTCBBitY;OSRdyTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;OSTCBPrioTbl[prio] = (OS_TCB *)OSTCBCur;}OSTCBPrioTbl[pip] = (OS_TCB *)1;if (pevent->OSEventGrp != 0x00) { prio = OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX);pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;pevent->OSEventCnt |= prio;pevent->OSEventPtr = OSTCBPrioTbl[prio];OS_EXIT_CRITICAL();OS_Sched();return (OS_NO_ERR);}pevent->OSEventCnt |= OS_MUTEX_AVAILABLE;pevent->OSEventPtr = (void *)0;OS_EXIT_CRITICAL();return (OS_NO_ERR);}8.04 无等待地获取互斥型信号量, OSMutexAccept()#if OS_MUTEX_ACCEPT_EN > 0INT8U OSMutexAccept (OS_EVENT *pevent, INT8U *err) {#if OS_CRITICAL_METHOD == 3OS_CPU_SR cpu_sr;#endifif (OSIntNesting > 0) {*err = OS_ERR_PEND_ISR;return (0);}#if OS_ARG_CHK_EN > 0if (pevent == (OS_EVENT *)0) {*err = OS_ERR_PEVENT_NULL;return (0);}if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { *err = OS_ERR_EVENT_TYPE;return (0);}#endifOS_ENTER_CRITICAL();if ((pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_A V AILABLE) {pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;pevent->OSEventCnt |= OSTCBCur->OSTCBPrio;pevent->OSEventPtr=(void*)OSTCBCur;OS_EXIT_CRITICAL();*err = OS_NO_ERR;return (1);}OS_EXIT_CRITICAL();*err = OS_NO_ERR;return (0);}#endif8.05获取互斥型信号量的当前状态, OSMutexQuery()#if OS_MUTEX_QUERY_EN > 0INT8U OSMutexQuery (OS_EVENT *pevent, OS_MUTEX_DATA *pdata) {#if OS_CRITICAL_METHOD == 3OS_CPU_SR cpu_sr;#endifINT8U *psrc;INT8U *pdest;if (OSIntNesting > 0) {return (OS_ERR_QUERY_ISR);}#if OS_ARG_CHK_EN > 0if (pevent == (OS_EVENT *)0) {return (OS_ERR_PEVENT_NULL);}if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { return (OS_ERR_EVENT_TYPE);}#endifOS_ENTER_CRITICAL();pdata->OSMutexPIP = (INT8U)(pevent->OSEventCnt >> 8);pdata->OSOwnerPrio=(INT8U)(pevent->OSEventCnt&OS_MUTEX_KEEP_LOWER_8);if (pdata->OSOwnerPrio == 0xFF) {pdata->OSValue = 1;} else {pdata->OSValue = 0;}pdata->OSEventGrp = pevent->OSEventGrp;psrc = &pevent->OSEventTbl[0];pdest = &pdata->OSEventTbl[0];#if OS_EVENT_TBL_SIZE > 0*pdest++ = *psrc++;#endif#if OS_EVENT_TBL_SIZE > 1*pdest++ = *psrc++;#endif#if OS_EVENT_TBL_SIZE > 2*pdest++ = *psrc++;#endif#if OS_EVENT_TBL_SIZE > 3*pdest++ = *psrc++; #endif#if OS_EVENT_TBL_SIZE > 4*pdest++ = *psrc++; #endif#if OS_EVENT_TBL_SIZE > 5*pdest++ = *psrc++; #endif#if OS_EVENT_TBL_SIZE > 6*pdest++ = *psrc++; #endif#if OS_EVENT_TBL_SIZE > 7*pdest = *psrc;#endifOS_EXIT_CRITICAL();return (OS_NO_ERR);}#endif。

相关文档
最新文档