RTX理解2

文献来源:http://wzhyblog.yo2.cn/articles/%E5%AE%9E%E6%97%B6%E7%B3%BB%E7%BB%9Frtx%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E4%B8%AD%E6%96%87%E7%BF%BB%E8%AF%91_4.html

实时系统RTX官方文档中文翻译_4

本文档包括以下内容:


进程间通讯

对象名称

命名的对象提供一种简单的方式供不同进程共享对象句柄。由创建其的进程指定的名称被限制在RTX_MAX_PATH字符(128个),并可以包括除了反斜杠/之外的任何字条。一旦一个进程创建了一个命名事件、互斥锁、旗语或共享内存对象,其他进程就可以使用此名称调用合适的函数(RtOpenEventRtOpenMutexRtOpenSemaphore, or RtOpenSharedMemory)来打开此对象的句柄。对象名称对大小写敏感。

事件、互斥锁、旗语或共享内存对象的名称共享相同的命令空间。如果指定一个由别的类型的对象正在使用的名称来创建对象时,创建函数会成功执行,但是GetLastError会返回ERROR_ALREADY_EXISTS。因此,创建一个命令对象时,使用唯一的名称,并确保函数返回值,以避免产生重命令错误。

例如,如果调用RtCreateMutex时指定的名称与当前已经存在的一个互斥锁对象重复时,此函数会返回已存在的那个对象的句柄。在这种情况下,调用RtCreateMutex其实就相当于调用了RtOpenMutex。有多个进程使用RtCreateMutex创建相同名称的mutex时,其实相当于其中一个进程调用了RtCreateMutex,而其他进程都调用了RtOpenMutex。然而,使用此技术来操作互斥锁对象时,其中任何一个调用的进程都不应请求对互斥锁对象的立刻拥有权(immediate ownership)。如果多个进程确实请求立刻拥有权,则就会很难分辨清是哪个进程实际获取了初始拥有权(initial ownership)。


共享内存

RTSS共享内存对象是一片非分页物理内存区域,它可以被映射到一个进程的虚拟地址空间。当一个共享内存对象有名字的时候,别的进程可以映射这个内存区域。一个共享内存对象可以被一个句柄和一个虚拟地址进行访问。为了使一个进程完全结束对一个共享内存对象的访问,它必须关闭其句柄。当所有进程结束它们对一个共享内存对象的访问时,会发生:

l 内存区域会返回到非分页内核内存池中

l 对象结束并退出

通过共享内存进行进程间通信

RTSS共享内存对象允许在包括RTSS进程和Win32进程在内的多个进程之间共享块数据。为了做到这一点,每个进程中的一个线程必须拥有其自己的唯一RTSS共享内存对象的进程相关句柄(process-relative handle),并且它自己的进程相关指针指向一个地址,这个地址是映射的虚拟地址储存的地方。这些句柄和指针可以通过调用RtCreateSharedMemory or RtOpenSharedMemory来获取。

使用RtCreateSharedMemory

为了使几个进程能够使用一个共享内存对象,此对象必须首先使用RtCreateSharedMemory创建。然后其他进程就可以使用其命名来映射这个共享内存对象。RtCreateSharedMemory返回一个句柄,并设置一个位置作为此共享内存的基地址。

如果要求的内存不能被分配,RtCreateSharedMemory就会失败,此时,没有内存被映射,也不会返回句柄。

如果有相同名称的共享内存对象已经存在,那么RtCreateSharedMemory将等同于RtOpenSharedMemory。如果RtCreateSharedMemory使用相同的名字但不同的大小来创建共享内存对象,RTX和Windows的动作有所区别。对于一个RTX进程,会返回第一次创建的共享内存的大小;对于一个Windows进程,只有请求的内存大小会被映射至进程空间。

使用RtOpenSharedMemory

RtOpenSharedMemory映射一个已经存在的共享内存对象。当一个共享内存对象被一个进程创建后,其他进程就通过调用RtOpenSharedMemory将此共享内存映射到它们的地址空间。如果指定的共享内存对象不存在,RtOpenSharedMemory就会失败。

RtOpenSharedMemory返回一个指向共享内存对象的句柄,并设置一个指向共享内存基地址的位置。当一个使用此共享内存的进程结束时,它应该结束指向此共享内存的句柄。

运行环境

RTSS共享内存对象一直被RTSS环境维持。但是,Win32进程可能会创建和打开RTSS共享内存对象。

RTSS共享内存对象是自命名的对象(is its own named object)。RtCreateSharedMemory 和 RtOpenSharedMemory调用隐式映射共享内存;这样避免了MapViewOfFile这个显式的Win32调用。当共享内存对象被创建时,RTSS使用非分页内存来支持此对象。


旗语对象

RTX旗语对象是一种维持一个在0到指定最大值之间计数器的同步对象。每次一个线程线束等待此旗语对象后这个计数器会减1;而在此旗语释放时会以一个变量的值增加。当此计数器变为0时,旗语对象的状态就不再是可通讯的,并且直到一些线程增加此计数器之前没有线程能够完成等待这个旗语对象。

像Win32旗语对象一样,RTSS旗语对象用来计算资源。它们可以给一个线程计算可用资源数量的能力;如果一个或多个资源可用,可用资源的计数被减少。RTSS旗语会自动执行这种“测试和设置”操作;也就是说,当从一个RTSS旗语请求一个资源时,操作系统会检查此资源是否可用,并减少可用资源计数,而不用通过另外一个线程接口。只有当资源计数已经减少之后,系统才会允许另外一个线程去请求资源。

因为几个线程可以影响一个RTSS旗语资源计数,一个RTSS旗语,不像RTSS互斥锁,不能被一个线程拥有。这意味着等待旗语对象:

l 永远不会返回WAIT_ABANDONED

l 一个线程中止时可能会丢失旗语资源

然而,与Win32旗语对象不同,RTSS旗语对象支持等待优先级。这意味着,当有几个不同优先级的线程等待RTSS旗语对象时,系统会按线程优先级的顺序来安排获取它的顺序。

通过旗语进行进程间通信

对一个RTSS旗语对象,每个进程中的线程都必须有它自己的进程相关句柄。这些句柄可以通过调用RtCreateSemaphore or RtOpenSemaphore来获得。

1. 使用RtCreateSemaphore

这是首先使用也是最常使用的一种方式,将RTSS旗语名称的参数作为标识字符串传递出去。第一个调用RtCreateSemaphore的线程会使系统产生RTSS旗语对象。别的线程再调用RtCreateSemaphore时,系统会判决拥有指定名称的RTSS旗语对象是否已经存在;结果是,系统不会产生一个新的旗语对象,但是会返回一个标明已存在的RTSS旗语对象的进程相关句柄。

在调用RtCreateSemaphore之后立即使用GetLastError,可判别RtCreateSemaphore是否产生了一个新的旗语对象。如果GetLastError报告ERROR_ALREADY_EXISTS,则没有产生一个新的旗语对象。

2. 使用RtOpenSemaphore

另外一种获得旗语对象句柄的方法是调用RtOpenSemaphore。参数dwDesiredAccess被忽略。lpName参数是旗语对象的0终止字符串名称。当调用RtOpenSemaphore之后,系统会扫描所有旗语对象,看是否有同样名为lpName的旗语对象存在。如果存在,则系统会创建一个表明此旗语对象的句柄,并返回调用线程的句柄。调用进程中的任何线程此时在任何可以获得此旗语句柄的函数中都可以使用此句柄。如果不存在,会返回null。

环境

RTSS旗语对象通常被RTX环境所维护。但是Win32程序可以创建、打开、释放和等待RTSS旗语。这使得RTSS和Win32进程中可以进行互操作。旗语命令空间与Win32旗语命令空间是分开的。


事件对象

事件对象是一种同步对象,它的状态可以使用RtCreateEventRtPulseEvent来显式的进行设置以供触发。有两种类型的事件:

Manual-reset event — 在显式地用RtCreateEvent置为不可触发之前,其状态会一直保持可触发状态。当它被触发时,任何等待的线程,或者是调用RtWaitForSingleObject指明同一个事件对象的线程都会被释放。

Auto-reset event — 直到一个等待线程被释放之前,其状态一直保持可触发状态,然后系统会自动将其状态置为不可触发状态。如果没有等待线程,这个事件对象会一直保持可触发状态。

一个事件对象在给一个线程发送信号时很有用,表明一个特殊的事件发生了。

1. 使用RtCreateEvent

一个线程使用RtCreateEvent函数创建一个事件对象,并指明其初始状态和其类型是manual-reset 还是 auto-reset,还可以为此事件对象指定一个名称。其它进程中的线程就可以通过在RtOpenEvent中指明其名称来打开此事件对象。更多关于对象名称的信息,请看:Object Names(对象名称,即本文档第一节内容)。

2. 使用RtPulseEvent

一个线程使用RtPulseEvent将一个事件对象的状态设置为可触发,并在释放期望数量的等待线程之后将其重置为不可触发状态。对于一个manual-reset类型的事件对象,所有等待线程会被释放。对于一个auto-reset类型的事件对象,此函数只会释放一个等待线程,即使有多个线程在等待。如果没有等待线程,RtPulseEvent会将此事件对象设置为不可触发并返回。


互斥锁对象

RTSS互斥锁对象是一种同步对象,当它不被任何线程拥有时,其状态为可触发;一旦被一个线程拥有时,其状态就不可触发。互斥锁用来仲裁对一个共享资源的独占式访问。

拥有权(Ownership)

一个线程在等待函数结束和调用RtReleaseMutex函数的期间拥有互斥锁。在这些调用之间,其他的线程不能拥有此互斥锁。如果互斥锁被拥有(没有触发)期间,有另外一个调用一个等待函数,则在互斥锁拥有者释放之前此等待函数不会结束(exit)。当互斥锁拥有者线程中止时,互斥锁被触发并被抛弃。等待者从等待函数的返回值中得到被抛弃的互斥锁。一个获得被抛弃的互斥锁的线程应该期望得到一个不一致的共享资源。

如果多于一个的线程在等待拥有权,则最高优先级的线程会获得拥有权,并且会从等待函数中第一个返回。在多个有相同优先级的线程等待成为拥有者时,最先请求的线程会得到之。

通过互斥锁进行进程间通信

对一个RTSS互斥锁对象,为了在多个进程(包括RTSS进程和Win32进程)中同步线程,每个进程中的线程都必须有它自己的进程相关句柄。这些句柄可以通过调用RtCreateMutex or RtOpenMutex来获得。

1. 使用RtCreateMutex

这是首先使用也是最常使用的一种方式,将RTSS互斥锁名称的参数作为标识字符串传递出去。第一个调用RtCreateMutex的线程会使系统产生RTSS互斥锁对象。别的线程再调用RtCreateMutex时,系统会判决拥有指定名称的RTSS互斥锁对象是否已经存在;结果是,系统不会产生一个新的互斥锁对象,但是会返回一个标明已存在的RTSS互斥锁对象的进程相关句柄。

在调用RtCreateMutex之后立即使用GetLastError,可判别RtCreateMutex是否产生了一个新的旗语对象。如果GetLastError报告ERROR_ALREADY_EXISTS,则没有产生一个新的互斥锁对象。如果你期望同其它进程共享这个RTSS互斥锁,可以忽略最后的这一步。

2. 使用RtOpenMutex

另外一种获得旗语对象句柄的方法是调用RtOpenMutex。参数dwDesiredAccess被忽略。lpName参数是旗语对象的0终止字符串名称。当调用RtOpenMutex之后,系统会扫描所有互斥锁对象,看是否有同样名为lpName的互斥锁对象存在。如果存在,则系统会创建一个表明此互斥锁对象的句柄,并返回调用线程的句柄。调用进程中的任何线程此时在任何可以获得此互斥锁句柄的函数中都可以使用此句柄。如果不存在,会返回null。

环境

RTSS互斥锁对象通常被RTX环境所维护。但是Win32程序可以创建、打开、释放和等待RTSS互斥锁。这使得RTSS和Win32进程中可以进行互操作。互斥锁命令空间与Win32旗互斥锁语命令空间是分开的。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值