tag 标签: 信号量

相关博文
  • 热度 18
    2014-6-30 01:07
    1438 次阅读|
    0 个评论
      1 、信号量是啥 : μ C/OS-II 的编写者 Jean 在他的书中写道:信号量实际上是一种约定机制,在多任务内核中普遍使用; μ C/OS-II 中的信号量由 16 位的无符号整型的信号量计数器( 0~65535 )和由等待该信号量的任务组成的任务等待表两部分组成;它的职责是什么呢?有三种: ( 1 )控制共享资源的使用权; ( 2 )标志着某事件的发生; ( 3 )使两个任务的行为同步;    就如同一群病人等着看医生一样,任务就是病人,内核就是医生,医生在一个时间内只能处理一个病人,医生发出一张绿卡说谁拿到了绿卡就进来看病吧。那么信号量就相当于这张绿卡,任何一个任务要被运行,就需要先拿到信号量。其他没拿到信号量的任务只好“挂起”继续排队等,直到内核处理完当前任务(医生看完当前病人);   信号量的约定机制使用的位数( 8 位、 16 位、 32 位)决定了信号量的取值范围( 2^8,2^16,2^32 ) ; 当信号量只有两个值 0 和 1 的时候,就被称为二值信号量。信号量有效意味着必须大于 0 ,为 0 则无效;    对信号量的操作有三种: ( 1 )初始化(或叫建立):需要给信号量赋初值; ( 2 )等信号(或叫挂起):等待信号量的任务表必须清空; ( 3 )给信号(或叫发信号):任务以“发信号 / 给信号”来释放信号量; 如果没有任务等待信号量,那么信号量只需要简单地加 1 就好;如果有任务等待,那么下一个任务直接进入就绪状态,然后信号量不用加 1 ;那么哪个任务获得信号量呢?很多内核的处理方法只有两种: ( 1 )按排队规矩来,即是 FIFO, 先入先出,哪个病人先来就先就诊; ( 2 )等待任务中优先级最高的那个,就是说哪个病人最严重,最需要尽快治疗的; 然而需要注意的是:   μ C/OS-II 这个医生很怪,只接受第二种,理由是它是可剥夺型内核:优先级高的先来!哪个病人病得不行了快挂了,那肯定得先让他先来。正在治疗中的病人(正在执行中的任务),不好意思,你先一边去等会(被挂起);等我处理完这个比你更高优先级的家伙再说。     在使用信号量之前,一定要就进行初始化,而且作为互斥条件,信号量必须初始化为 1 ;     信号量使用事件控制块的成员 OSEvent Cnt 作为计数器,而用 OSEvevtTbl[] 数组来作为等待任务表。 2 、什么时候该用信号量     Je an 在他的书中讲得很明确,尽管信号量比较好用,但是也不要对信号量过分使用,因为请求和释放信号量的过程也是要费蛮多时间的;比如,共享简单的变量只需要关、开中断就可以了,而没必要使用信号量。当开关中断都无法处理时候,就考虑用信号量,例如共享变量是浮点数,关中断时间过长会影响中断延迟时间,所以就应该用信号量。      
  • 热度 16
    2014-6-30 01:06
    1457 次阅读|
    0 个评论
      3 、怎么用信号量:    μ C/OS-II 提供了以下 6 个操作信号量的函数供用户使用,但是在使用这些函数之前,要在 OS_CFG.H 中配置使能,告诉 μ C/OS-II-- 我要用这几个函数了! #define    OS_SEM_EN                 1 #define    OS_SEM_ACCEPT_EN          1 #define    OS_SEM_DEL_EN             1 #define    OS_SEM_PEND_ABORT_EN      1 #define    OS_SEM_QUERY_EN           1 #define    OS_SEM_SET_EN             1 ( 1 )建立一个信号量: OSSem Create() 程序原型是 OS_EVENT *OSSemCreate(INT16U cnt) 由此可知,调用 OSSem Create() 来建立信号量。必须给信号量赋予初始值, 0~65535 。分三种情况: A : 若信号量用来表示一个或多个事件发生,那么初始化为 0 ; B : 若信号量用来对共享资源的访问,那么初始化为 1 ; C : 若信号量用来表示允许访问 N 个相同的资源,比如说用信号量管理缓冲区阵列,然后该阵列包含 N 个缓冲区,那么这时候应该初始化为 N; 并且该信号量是可计数的。 ( 2 )删除一个信号量: OSSemDel() 使用时候注意: A:         因为可能是多个任务要使用一个信号量,那么在删除该信号量时候应该首先删除该信号量的所有任务! B:         只能在任务中删掉信号量,而不能在中断服务函数中删掉; 程序原型是 OS_EVENT  *OSSemDel (OS_EVENT  *pevent,   // 信号量的指针                      INT8U      opt,         // 删除条件选项                      INT8U     *perr)     // 错误信息 ① *pevent :   指明你要干掉哪一个信号量! ② opt          :    这里有两个选择                             A:   OS_DEL_NO_PEND   只有当没有任务在等待该信号量的时候,你就删吧。。                             B:   OS_DEL_ALWAYS     对不起,我不管了,无论有木有任务在等你(信号量),我都必须马上带你走! ③ *perr     :     这里是作为删除失败后的错误信息提示返回的。有以下六种可能,任哲中的书就说了删除成功就会返回 OS_ERR_NONE    。                             A: OS_ERR_NONE   成功干掉信号量                             B: OS_ERR_DEL_ISR   你现在是从中断服务函数中对信号量下手,这是非法的,出去后再动手吧。。                             C: OS_ERR_INVALID_OPT   你选择了一个非法的 Opt , 我在前面说了,只有两个选择 A 或 B !!你丫不听!                             D:  OS_ERR_TASK_WAITING   你选了 OS_DEL_NO_PEND 作为 opt , 但是不幸的是,还有任务在等着她。。所以你必须再等等、、、                             E: OS_ERR_EVENT_TYPE   你不是通过指针来指向一个信号量的,所以不对。。                             F: OS_ERR_PEVENT_NULL 你所提供的 pevent 居然是个空指针,果断不行啊!!! ( 3 )等待一个信号量 OSSemPend void  OSSemPend (OS_EVENT  *pevent,       // 信号量的指针                  INT32U     timeout,    // 等待的时间限制。我顶多等你那么久,过时不候,直接进入就绪状态                  INT8U     *perr)          // 错误信息 ( 4 )发送一个信号量 INT8U  OSSemPost (OS_EVENT *pevent)        // 信号量的指针   ( 5 )无等待地请求一个信号量 INT16U  OSSemAccept (OS_EVENT *pevent)    // 信号量的指针   ( 6 )查询一个信号量的当前状态 INT8U  OSSemQuery (OS_EVENT     *pevent,        // 信号量的指针                    OS_SEM_DATA  *p_sem_data) // 一个指向保存有关信号量信息的结构体的指针
  • 热度 25
    2014-6-27 16:07
    2530 次阅读|
    0 个评论
       uC/OS-II的特点是主要有一个内核,只有任务管理和任务调度,无文件系统,界面系统,外设管理系 统等。小巧,源代码公开,实时性强,可移植性好,多任务,基于优先级的可剥夺型调度。    先挑几个有用的说一说,可裁剪:它的系统服务函数中定义了条件编译开关量,对不需要的服务可以 通过条件编译予以裁剪,只使用里面的应用程序需要的那些系统服务。代码可裁剪到2K左右。    可剥夺:它完全是可剥夺型的实时内核,也就是说已经准备就绪的高优先级任务总是可以剥夺正在运 行的低优先级的任务的CPU使用权。(这一点我们在写程序时一定要注意)    多任务:可以管理64个任务,不同版本支持的任务数有差别,赋予每个任务的优先级必须是不同的, 这也就是说它不支持时间片轮转调度发(该调度法适用于调度优先级相同的任务)。    可确定性:它绝大部分函数的执行时间具有可确定性,除了函数OSTimeTick()和某些时间标志服务外, 它的系统服务执行时间不依赖于应用程序任务数目的多少,用户总是能知道它函数调用**务执行了多长 时间。    任务栈:它允许每个任务都有自己单独的栈,可以自行定义它的大小。    中断管理:它的中断嵌套层数可达255层,中断可使正在执行的任务暂时挂起,如果中断使更高优先级 的任务进入就绪,则高优先级的任务在中断嵌套全部退出后立即执行。  uC/OS-II的内核中10个文件与微处理器类型无关,移植后无需修改. 这类文件包括:  OS_CORE.C  OS_FLAG.C  OS_MBOX.C  OS_MEN.C   OS_MUTEX.C           OS_SEM.C   OS_TASK.C  uCOS_II.C  OS_TIME.C  OS_Q.C    3个文件与CPU类型相关 它们是:         OS_CPU_C.C  OS_CPU.H OS_CPU.ASM    2个文件与具体的应用有关 它们是:  OS_CFG.H  INCLUDE.H    事件:一个任务或者中断服务子程序可以通过内核服务来向另外的任务发信号。 最一般的事件包括:信号量,消息队列,互斥信号量,消息邮箱,事件标志组等。    信号量是一种通信机制。信号量:有两种类型,其一支取0,1两个值的二值信号量;其二由若干位组 合成的计数式信号量一般有8位,16位,32位等,具体是多少位取决于内核。    P/V操作普遍应用与内核,其主要作用有三点:    其一满足互斥条件,实现共享资源的独占使用;其二标志某事件的发生;其三使两个任务行为同步。信号量就像一块令牌,谁先拿到令牌,谁就能运行;得不到就只有等待。    信号量是一个受保护的量,只有初始化和P/V操作才能改变信号量的值,其工作原理是:     (1)初始化信号量也叫建立信号量。信号量初始化时,要给信号量赋初值,等待信号量的任务列表清空。     (2)等信号(P)或申请信号量叫挂起(PEND)。对于执行等待信号量的任务来说,若该信号有效,则信号量值减1,任务继续执行,若信号量值位0,则任务继续被挂起。若内核允许被定义等待超时后,则超时后,给任务转入就绪,同时返回错误代码以示发生了超时错误。     (3)给信号(V)叫发信号(POST)。若没有任务等待该信号量,则信号量值仅简单加1;若只有一个任务等待该信号量,则任务转入就绪状态,信号量的值不加1;若有多个任务等待信号量,至于谁先得到信号量,那就得看内核是如何调度的了。一般有两种可能:其一是按优先级原则,等待信号量的任务中优先级最高的先得到;其二是按先进先出原则,最早开始等待信号量的那个任务先得到。uC/OS-II只支持优先级法。
  • 热度 26
    2014-1-14 23:45
    1866 次阅读|
    3 个评论
    进程间通信——信号量、互斥锁等的异同   最早接触在系统上编程,是在嵌入式Linux上完成几项功能。当时就是按照写单片机程序的思维写的。实现几个功能,就用了一个进程,单线程来做。 后来实习时,接触Linux下多进程,多线程的编程。了解到多个线程之间的操作需要进行同步,互斥等。 在工作后,有进行了uCOS的多任务编程。发现uCOS中的多任务的同步,互斥与Linux下有很多相似性。但是也有很多不同。 也因为一开始把uCOS的信号量,互斥锁等和Linux类比来操作。概念确实是一致的,但是由于具体实现的差异,也导致了实际操作中的一些失误(uCOS中的任务相当于进程中的线程,任务间通信相当于线程间通信)。 虽然,经过这些实践,但是有些疑问却一直没有解开。   在一篇博客中到关于深入了解系统的书籍推荐找到了《UNIX网络编程第二卷:进程间通信》,说道它介绍了信号量等IPC通信(但是它也说了,这些技术是老掉牙的技术)。 不过这本书确实解开了不少一直来的疑惑。   传统设计原则认为:把应用程序设计为一组互相通信的小片段比将其设计为单个庞大的程序更好。 应用程序的几种构建方法: 1、用一个庞大的程序完成全部工作。 2、使用多个程序,程序之间用某种形式的IPC进行通信; 3、使用一个包含多个线程的程序,线程之间使用某种IPC。 注:IPC:Interprocess Communication,进程间通信。 在自己最早的时候使用的就是第一种方式来构建程序的。   对于UNPv2,主要介绍了4种不同的IPC方式: 1、消息传递; 2、同步(互斥量、条件变量、读写锁、文件和记录锁、信号量); 3、共享内存; 4、远程过程调用。   由于更多的是在单进程中实现多线程通信,对于同步的使用要多于消息传递。因为在单进程中,所有线程共享运行地址空间。全局变量(以及局部静态变量(通过访问函数))所有线程可以访问。所以对于同步的使用要多于消息传递。也因此对于互斥量,信号量,条件变量等何时使用,如何使用留下了疑问。 一开始,自己把互斥锁和信号量几乎没有怎么区分,只要实现了对临界区的保护就可以。也感觉他们之间似乎没什么差异,还纳闷为什么会有了互斥锁还有信号量存在。 在已经有了互斥锁的时候,还提供信号量,Posix.1给出的理由是:提供信号量的主要目的是提供一种进程间同步方式。这些进程可能共享也可能不共享内存区。互斥锁,条件变量是作为线程间同步机制说明的,这些线程总是共享某个内存区(因为线程共享运行地址空间)。这两者都是已经广泛用了很多年的同步范式。每组原语都特别适合于特定的问题。 应该可以理解为,互斥锁,条件变量,信号量都可以作为同步来使用,不必纠结于需要同步时使用那一个。但是每一个都用了很长时间,都有自己特别适合的问题。所以就都留着了。 也就因为有自己最合适的问题,所以它们之间肯定有些地方很不一样。 以下是:信号量,互斥锁,条件变量三者的一些差别: 1、互斥锁总是要由给它上锁的线程解锁,信号量的挂出却不必由执行过它的等待操作的统一线程执行。 2、互斥锁要么被锁住,要么被解开(二值状态,类似于二值信号量,区别于多值信号量)。 3、既然信号量有一个与之关联的状态(它的计数值),那么信号量挂出操作总是被记住。而当向一个条件变量发送信号时,如果没有线程等待在盖条件变量,则该信号丢失。(即:如果在信号量挂出的时候,没有线程等待此信号量,则在下次有线程等待的时候,会收到此信号量,并进行处理。而条件变量则将会陷入等待) 4、在Posix.1标准中,各种同步技巧(互斥锁,条件变量,读写锁,信号量)中,只有信号量挂出操作,能够在信号处理程序中安全调用。 从这几点看,似乎信号量很有优势,但也因为功能强大,所以其运行开销会偏大。具体的性能,需要实际在系统中测试才知道。   UNPv2在最后关于解决问题使用哪种IPC给出的解答是:对于解决特定问题使用哪种IPC,应该视具体问题而定。我们可以做的是,熟悉各种IPC机制,然后根据具体需要选择一个适合当前的。   关于消息传递一块,个人感觉:远程过程调用和共享内存,都是实现了一种消息传递的方式,或者更准确的说是数据传递。虽然对于具体实现技术上来说,有四种IPC方式,但是从数据传递和同步来看,只有两种。一种实现临界区保护,一种实现信息的传递。   在uCOS中也有一些对应于这些IPC方式的实现(当然是任务间通信): 1、消息传递(邮箱,消息队列); 3、同步(信号量,互斥锁,邮箱(可以作为互斥来用)); 由于uCOS中的代码,共享内存空间,所以全局变量就相当于内存共享。所以在使用uCOS的时候,更多的参照线程间通信的方式,来操作。但是就像文前提到的,uCOS毕竟不遵守Posix.1标准,所以在实现上不一样。 在Linux上信号量很多时候是二值信号量(不知道最新的是否支持多值),但是uCOS支持的信号量是多值信号量。由于一开始将uCOS上的信号量类比于Linux上的信号量,也当做二值来处理,结果程序的运行结果不符合预期。   虽然很多概念是适用的,但是当针对于具体应用的时候,还是要看具体的实现是怎么样子的。这样才会避免一些细节上的问题。而且对于嵌入式编程而言,IPC技术不但不是老掉牙的技术,相反还是十分重要的。因为嵌入式开发中,有时候使用的操作系统,是共享地址空间的。而且有时候,要实现多任务,多线程等同步操作就是其中实现任务或者线程间协作的很重要的一个步骤。即使开发裸机系统,出去性能考虑会实现为异步式的。而异步就要考虑很多资源的同步问题,其实也就是做一个操作系统的一些工作——调度。   由于现在Linux等操作系统对于这些高度抽象,似乎不用去考虑这些。但是对于嵌入式编程而言,这些还是要经常面对的问题。 IPC对于嵌入式开发,还不过时。   注: http://coolshell.cn/articles/4990.html 技术员技术练级攻略 《UNPv2》 《 嵌入式实时操作系统μC/OS-2 》
  • 热度 17
    2013-9-12 21:51
    1858 次阅读|
    0 个评论
    引用      阐述P,V原语的理论不得不提到的一个人便是赫赫有名的荷兰科学家 E.W.Dijkstra。如果你对这位科学家没有什么印象的话,提起解决图论中最短路径问题的Dijkstra算法应当是我们再熟悉不过的了。P,V原 语的概念以及P,V操作当中需要使用到的信号量的概念都是由他在1965年提出的。  信号量是最早出现的用来解决进程同步与互斥问题的机制(也可实现进程通信),包括一个称为信 号量的变量及对它进行的两个原语操作。信号量为一个整数,我们设这个信号量为:sem。很显然,我们规定在sem大于等于零的时候代表可供并发进程使用的 资源实体数,sem小于零的时候,表示正在等待使用临界区的进程的个数。根据这个原则,在给信号量附初值的时候,我们显然就要设初值大于零。 p操作和v操作是不可中断的程序段,称为原语。P,V原语中P是荷兰语的Passeren,相当于英文的pass, V是荷兰语的Verhoog,相当于英文中的incremnet。 且在P,V愿语执行期间不允许有中断的发生。 对于具体的实现,方法非常多,可以用硬件实现,也可以用软件实现。这种信号量机制必须有公共内存,不能用于分布式操作系统,这是它最大的弱点。 ------------------------------------------------------------- 首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:   P(S):①将信号量S的值减1,即S=S-1;   ②如果S=0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。   V(S):①将信号量S的值加1,即S=S+1;   ②如果S0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。 PV操作的意义:我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。 什么是信号量?信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该 信号量的下一个进程。信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的 进程个数。注意,信号量的值仅能由PV操作来改变。 一般来说,信号量S=0时,S表示可用资源的数量。执行一次P操作意味着请求分配一个单位资源,因此S的值减1; 当S0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能运行下去。而执行一个V操作意味着释放一个单位资源,因此S的值加1; 若S=0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。   利用信号量和PV操作实现进程互斥的一般模型是: 进程P1 进程P2 …… 进程Pn …… …… …… P(S); P(S); P(S); 临界区; 临界区; 临界区; V(S); V(S); V(S); …… …… …… ……   其中信号量S用于互斥,初值为1。   使用PV操作实现进程互斥时应该注意的是: (1)每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。 (2)P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。 (3)互斥信号量的初值一般为1。   利用信号量和PV操作实现进程同步 PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来,当信号量的值为0时,表示期望的消息尚未产生;当信号量的值非0时,表示期望的消息已经存在。用PV操作实现进程同步时,调用P操作测试消息是否到达,调用V操作发送消息。   使用PV操作实现进程同步时应该注意的是: (1)分析进程间的制约关系,确定信号量种类。在保持进程间有正确的同步关系情况下,哪个进程先执行,哪些进程后执行,彼此间通过什么资源(信号量)进行协调,从而明确要设置哪些信号量。 (2)信号量的初值与相应资源的数量有关,也与P、V操作在程序代码中出现的位置有关。 (3)同一信号量的P、V操作要成对出现,但它们分别在不同的进程代码中。 【例1】生产者-消费者问题 在多道程序环境下,进程同步是一个十分重要又令人感兴趣的问题,而生产者-消费者问题是其中一个有代表性的进程同步问题。下面我们给出了各种情况下的生产者-消费者问题,深入地分析和透彻地理解这个例子,对于全面解决操作系统内的同步、互斥问题将有很大帮助。 (1)一个生产者,一个消费者,公用一个缓冲区。 定义两个同步信号量: empty——表示缓冲区是否为空,初值为1。 full——表示缓冲区中是否为满,初值为0。 生产者进程 while(TRUE){   生产一个产品;   P(empty);   产品送往Buffer;   V(full);   } 消费者进程 while(TRUE){   P(full);   从Buffer取出一个产品;   V(empty);   消费该产品;   } (2)一个生产者,一个消费者,公用n个环形缓冲区。 定义两个同步信号量: empty——表示缓冲区是否为空,初值为n。 full——表示缓冲区中是否为满,初值为0。   设缓冲区的编号为1~n61485;1,定义两个指针in和out,分别是生产者进程和消费者进程使用的指针,指向下一个可用的缓冲区。 生产者进程 while(TRUE){   生产一个产品;   P(empty);   产品送往buffer(in);   in=(in+1)mod n;   V(full);   } 消费者进程 while(TRUE){ P(full);   从buffer(out)中取出产品;   out=(out+1)mod n;   V(empty);   消费该产品;   } (3)一组生产者,一组消费者,公用n个环形缓冲区   在这个问题中,不仅生产者与消费者之间要同步,而且各个生产者之间、各个消费者之间还必须互斥地访问缓冲区。 定义四个信号量: empty——表示缓冲区是否为空,初值为n。 full——表示缓冲区中是否为满,初值为0。 mutex1——生产者之间的互斥信号量,初值为1。 mutex2——消费者之间的互斥信号量,初值为1。   设缓冲区的编号为1~n61485;1,定义两个指针in和out,分别是生产者进程和消费者进程使用的指针,指向下一个可用的缓冲区。 生产者进程 while(TRUE){   生产一个产品;   P(empty);   P(mutex1);   产品送往buffer(in);   in=(in+1)mod n;   V(mutex1);   V(full);   } 消费者进程 while(TRUE){ P(full);   P(mutex2);   从buffer(out)中取出产品;   out=(out+1)mod n;   V(mutex2);   V(empty);   消费该产品;   }   需要注意的是无论在生产者进程中还是在消费者进程中,两个P操作的次序不能颠倒。应先执行同步信号量的P操作,然后再执行互斥信号量的P操作,否则可能造成进程死锁。 【例2】桌上有一空盘,允许存放一只水果。爸爸可向盘中放苹果,也可向盘中放桔子,儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。规定当盘空时一次只能放一只水果供吃者取用,请用P、V原语实现爸爸、儿子、女儿三个并发进程的同步。 分析 在本题中,爸爸、儿子、女儿共用一个盘子,盘中一次只能放一个水果。当盘子为空时,爸爸可将一个水果放入果盘中。若放入果盘中的是桔子,则允许儿子吃,女 儿必须等待;若放入果盘中的是苹果,则允许女儿吃,儿子必须等待。本题实际上是生产者-消费者问题的一种变形。这里,生产者放入缓冲区的产品有两类,消费 者也有两类,每类消费者只消费其中固定的一类产品。   解:在本题中,应设置三个信号量S、So、Sa,信号量S表示盘子是否为空,其初值为l;信号量So表示盘中是否有桔子,其初值为0;信号量Sa表示盘中是否有苹果,其初值为0。同步描述如下: int S=1; int Sa=0; int So=0;   main()   {   cobegin   father(); /*父亲进程*/   son(); /*儿子进程*/   daughter(); /*女儿进程*/   coend   }   father()   {   while(1)   {   P(S);   将水果放入盘中;   if(放入的是桔子)V(So);   else V(Sa);   }   }   son()   {   while(1)   {   P(So);   从盘中取出桔子;   V(S);   吃桔子;   }   }   daughter()   {   while(1)   {   P(Sa);   从盘中取出苹果;   V(S);   吃苹果;   }   } 思考题: 四个进程A、B、C、D都要读一个共享文件F,系统允许多个进程同时读文件F。但限制是进程A和进程C不能同时读文件F,进程B和进程D也不能同时读文件F。为了使这四个进程并发执行时能按系统要求使用文件,现用PV操作进行管理,请回答下面的问题:   (1)应定义的信号量及初值: 。   (2)在下列的程序中填上适当的P、V操作,以保证它们能正确并发工作:   A() B() C() D()   { { { {   ; ; ; ;   read F; read F; read F; read F;   ; ; ; ;   } } } }   思考题解答: (1)定义二个信号量S1、S2,初值均为1,即:S1=1,S2=1。其中进程A和C使用信号量S1,进程B和D使用信号量S2。 (2)从 到 分别为:P(S1) V(S1) P(S2) V(S2) P(S1) V(S1) P(S2) V(S2) 信号量、PV操作是解决进程间的同步与互斥问题的。 ★ 做题时尤其要注意隐藏的同步、互斥问题。这些问题通常可以归入生产者-消费者问题和阅读者-写入者问题。 ★ PV操作一定是成对出现的,但是这不意味着它会在一个进程内成对出现。 ★ 在互斥关系中,PV操作一定是在一个进程内成对出现。而且,信号一定大于0,具体多少视情况而定。而对于同步关系,则一对PV操作在两个进程或者更多的进程中出现。 ★ 对于同步关系,信号量可能为0,也可能不为0;用于同步的信号个数可能1个,也可能是多个。 ★ 对信号量为1的,应该先执行V操作。 ★ 在生产者-消费者问题中,要设置三个信号量:empty-空闲的缓存区数量,初值为n;full-已填充的缓存区数量,初值为0;mutex-保证只有一个进程在写入缓存区,初值为1。 ★ 在阅读者-写入者问题中,设置两个信号量:信号量access-控制写入互斥,初值为1;信号量rc-控制对共享变量ReadCount(读者统计值)的互斥访问。
相关资源
  • 所需E币: 1
    时间: 2023-7-11 17:27
    大小: 1.11MB
    上传者: 张红川
    07system-VIPC通信信号量.pdf
  • 所需E币: 1
    时间: 2022-1-7 18:28
    大小: 788.5KB
    上传者: 西风瘦马
    uCOS-II信号量集
  • 所需E币: 1
    时间: 2022-1-8 10:42
    大小: 896.2KB
    上传者: 西风瘦马
    raw-os实例之——信号量同步
  • 所需E币: 0
    时间: 2021-3-10 20:13
    大小: 276.03KB
    上传者: czd886
    FPGA设计中信号量管理的硬件电路设计
  • 所需E币: 4
    时间: 2019-12-25 15:52
    大小: 189.22KB
    上传者: 二不过三
    介绍了CompactPCI总线及接口技术,PCI配置空间的内容与操作方法.详细说明了在VxWorks实时多任务操作系统下配置cPCI总线设备的方法.由于系统通过中断响应外部事件,使得硬件中断处理成为实时系统设计中的关键问题.在VxWo...第!"卷第!期核电子学与探测技术#$&%!"’$&!!(("年)月’*+%,-./%,+0.$12+345,0,+02$16,+71$%$89:-……
  • 所需E币: 3
    时间: 2019-12-25 12:16
    大小: 521KB
    上传者: rdg1993
    任务之间的通讯与同步第6章任务之间的通讯与同步16.0事件控制块ECB26.1初始化一个ECB块,OSEventWaitListInit()66.2使一个任务进入就绪状态,OSEventTaskRdy()76.3使一个任务进入等待状态,OSEventTaskWait()96.4由于等待超时将一个任务置为就绪状态,OSEventTO()96.5信号量106.5.1建立一个信号量,OSSemCreate()116.5.2等待一个信号量,OSSemPend()126.5.3发送一个信号量,OSSemPost()146.5.4无等待地请求一个信号量,OSSemAccept()166.5.5查询一个信号量的当前状态,OSSemQuery()176.6邮箱186.6.1建立一个邮箱,OSMboxCreate()196.6.2等待一个邮箱中的消息,OSMboxPend()206.6.3发送一个消息到邮箱中,OSMboxPost()226.6.4无等待地从邮箱中得到一个消息,OSMboxAccept()246.6.5查询一个邮箱的状态,OSMboxQuery()256.6.6使用邮箱作为二值信号量266.6.7使用邮箱实现延时,而不使用OSTimeDly()276.7消息队列28……
  • 所需E币: 3
    时间: 2019-12-25 10:33
    大小: 10.27MB
    上传者: 二不过三
    嵌入式操作系统原理……
  • 所需E币: 4
    时间: 2019-12-24 14:18
    大小: 1.55KB
    上传者: 16245458_qq.com
    uTenux实验2:信号量……