我应该使用Mutex OR Critical Section for Windows Mobile RIL

时间:2010-03-20 06:37:41

标签: winapi geolocation windows-mobile radio ril

我在Radio Layer Interface (RIL) Native APIs中使用Windows Mobile application。在此API中,大多数函数的返回值/结果不会立即返回,而是通过传递给RIL API的回调函数传递。

有些使用示例位于XDA Develompent ToolsGoogle Gears Geolocation API

我的问题是,在这两个示例中,互斥锁用于保护数据而不是其他同步对象。

现在,关键部分在这两个示例所描述的用例中是否可以正常使用?哪个线程或进程实际上会调用回调函数?

修改
我的代码只能从我的进程内部访问我的数据,但是哪个线程/进程在RIL API中调用回调函数?我的意思是,我将函数回调传递给RIL API,但是是否从其他进程调用了回调?在这种情况下,它将给出另一个解释为什么样本使用Mutex。如果RIL API实际上在我的进程中创建了一个线程并且它调用了我的回调函数,那么我认为Critical Section就可以了(并且它比互斥锁更快)。

更新
我的代码在我自己的进程中访问了(1)的数据,并且还从函数回调中修改了(2)。回调由RIL API完成。

我的问题:哪个线程/进程在RIL API中调用回调函数?

到目前为止的故事:
我:您好RIL先生,请把一些数据放到我的办公室(a.k.a变量)。
RIL:好的先生。我将稍后提交数据,我会在完成后发出信号(我在这里使用了一个事件)。

进入我的办公室需要门禁卡。如果RIL先生和我在同一家公司,RIL先生可以使用他自己的门禁卡进入我的办公室(就我而言,这意味着一个关键部分)。如果他来自其他公司,我需要为他设置访问卡/访客卡(在我的情况下,我需要一个互斥锁)。

如果RIL先生使用他自己的门禁卡,这意味着我不需要为他设置门禁卡/访客卡,这对我来说意味着更少的麻烦。 (即临界区比互斥锁更快)

问题是,我几天前刚刚遇到了RIL先生,我对他并不了解。我不知道他是否和我在同一家公司。 mentioned 的一个选项nobugz是为RIL先生建立一张访问卡,无论RIL先生是否与我在同一家公司。这样,RIL先生保证能够进入我的办公室。 (我的数据/变量保证是安全的)

现在我在我的代码中使用互斥锁(为RIL先生设置一个可能冗余的访问卡)。

啊哈!刚写完这篇文章时就有了主意。我想我会问RIL先生他是哪家公司的。这样,如果他和我在同一家公司,我将来不必为他设置访问卡。 (即将GetCurrentProcessId()GetCurrentThreadId()放入回调函数中)

4 个答案:

答案 0 :(得分:2)

Windows Mobile RIL通常位于device.exe(适用于WM6.x)。但是,当您的进程调用RIL时,您的调用将通过RIL代理传递。

RIL代理与您的流程链接并驻留在您的流程中,并为您处理与流程边界相关的所有问题(另外,这至少是需要打包所有RIL数据结构的部分原因)到已知大小的单个内存块中)。在内部,RIL代理创建一个执行回调的线程。

这意味着您的代码可以使用CRITICAL_SECTION对象来提供必要的同步/保护。

答案 1 :(得分:1)

使用互斥锁的关键是你不知道哪个线程可以进行回调。是的,关键部分也可以。小心,错误导致随机,非常难以诊断失败。

答案 2 :(得分:1)

关键部分互斥锁。关键部分与普通互斥体(至少主要)在某种程度上不同:它特定于一个进程,其中互斥体可以跨进程使用。

因此,在这种情况下,基本问题正是您正在保护的 - 如果它是您的程序中的数据,其他进程无法访问,那么关键部分应该很好地完成工作。如果您要保护两个进程共享的内容(如果用户要同时运行程序的两个实例),那么您可能需要一个互斥锁。

编辑:至于必须使用一个关键部分来保护RIL本身所做的事情,不,不需要(或者至少肯定不应该)。使用互斥锁,您可以通过打开具有相同名称的互斥锁来控制对共享资源的访问,从而指望所有进程协作。你不能指望它,所以如果需要,接口就完全坏了。

更新:除非他们在RIL中做了一些非常不寻常的事情,否则回调将在您的流程中发生,因此关键应该是足够的。如果它正在修改您的数据,这意味着您的数据被映射并且对该代码可见 - 这意味着关键部分中的数据中的数据也将被映射并可见,并且它将起作用。关键部分不起作用的时间是在处理单独的进程时,因此一个数据中的数据不会映射/显示给另一个。

答案 3 :(得分:0)

嗯,互斥体和关键部分之间的另一个区别(当然是Windows实现)是一个关键部分是可重入的 - 即同一个线程可以两次获取关键部分,而不必释放它。