我在用 无线电层接口 (RIL) 本机 APIWindows 移动应用程序. 。在此 API 中,大多数函数的返回值/结果不会立即返回,而是通过回调函数传递给 RIL API。

一些使用示例可以在以下位置找到 XDA 开发工具谷歌 齿轮 地理定位 应用程序编程接口.

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

现在,关键部分在这两个示例描述的用例中表现良好吗?哪个线程或进程将实际调用回调函数?

编辑:
我的代码只能从进程内部访问我的数据,但是哪个线程/进程正在调用 RIL API 中的回调函数?我的意思是,我向 RIL API 传递了一个函数回调,但是这些回调是从其他进程调用的吗?在这种情况下,它将给出另一个解释为什么示例使用互斥体。如果 RIL API 实际上在我的进程内创建了一个线程并且它调用我的回调函数,那么我认为关键部分会很好(而且它比互斥体更快)。

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

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

到目前为止的故事:
我: RIL 先生您好,请把一些数据放入我的办公室(又名变量)。
瑞尔: 好的,先生。我稍后会放置数据,完成后我会向您发出信号(我在这里使用了一个事件)。

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

如果RIL先生使用他自己的门禁卡,这意味着我不需要为他设置门禁卡/访客卡,这对我来说意味着更少的麻烦。(IE。关键部分比互斥体更快)

问题是,我几天前才认识这位RIL先生,对他了解不多。我不知道他和我是不是同一个公司的。一种选择是 提及 经过 诺布兹 就是为RIL先生设置一张门禁卡,无论RIL先生是否与我来自同一家公司。这样,RIL先生就可以保证能够进入我的办公室。(我的数据/变量保证是安全的)

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

啊哈!写这篇文章的时候突然有了一个想法。我想我就问问 RIL 先生他是哪家公司的。这样以后如果他和我在一个公司,我就不用再给他设置门禁卡了。(IE。放 GetCurrentProcessId()GetCurrentThreadId() 在回调函数中)

有帮助吗?

解决方案

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

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

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

其他提示

使用互斥体的要点是您不知道哪个线程可能会进行回调。是的,关键部分也可以工作。小心,错误会导致随机和 非常 很难诊断故障。

关键部分 互斥体。临界区与普通互斥体的不同之处在于(至少主要如此):它特定于一个进程,其中可以跨进程使用互斥体。

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

编辑:至于必须使用关键部分来保护 RIL 本身所做的事情,不,那不是(或者至少绝对不是) 不应该) 被需要。使用互斥体,您可以依靠所有进程通过打开同名互斥体来协作来控制对共享资源的访问。你不能指望这一点,所以如果需要它,界面就会完全损坏。

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top