- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我们正在基于 VxWorks 5.5 的专有嵌入式平台上进行编程。在我们的工具箱中,我们有一个条件变量,它是使用 VxWorks 二进制信号量实现的。
现在,POSIX 提供了一个等待函数,该函数也接受一个互斥体。这将解锁互斥锁(以便其他任务可能写入数据)并等待其他任务发出信号(完成写入数据)。我相信这实现了所谓的监视器,ICBWT。
我们需要这样一个等待函数,但实现它很棘手。一个简单的方法可以做到这一点:
bool condition::wait_for(mutex& mutex) const {
unlocker ul(mutex); // relinquish mutex
return wait(event);
} // ul's dtor grabs mutex again
但是,这具有竞争条件,因为它允许另一个任务在解锁之后和等待之前抢占该任务。另一个任务可以写入解锁后的日期,并在该任务开始等待信号量之前发出条件信号。 (我们已经对此进行了测试,并且确实会发生这种情况并永远阻止等待任务。)
鉴于 VxWorks 5.5 似乎没有提供 API 来在等待信号时暂时放弃信号量,有没有办法在提供的同步例程之上实现这一点?
注意: 这是一个非常老的 VxWorks 版本,已经 编译 没有 POSIX 支持(据我了解,由专有硬件的供应商提供)。
最佳答案
使用原生 vxworks 应该很容易,这里需要一个消息队列。您的 wait_for 方法可以按原样使用。
bool condition::wait_for(mutex& mutex) const
{
unlocker ul(mutex); // relinquish mutex
return wait(event);
} // ul's dtor grabs mutex again
但是等待(事件)代码看起来像这样:
wait(event)
{
if (msgQRecv(event->q, sigMsgBuf, sigMsgSize, timeoutTime) == OK)
{
// got it...
}
else
{
// timeout, report error or something like that....
}
}
你的信号代码会是这样的:
signal(event)
{
msgQSend(event->q, sigMsg, sigMsgSize, NO_WAIT, MSG_PRI_NORMAL);
}
因此,如果信号在您开始等待之前被触发,那么 msgQRecv 将在最终被调用时立即返回该信号,然后您可以如上所述在 ul dtor 中再次使用互斥锁。
event->q 是一个 MSG_Q_ID,它是在事件创建时调用 msgQCreate 创建的,sigMsg 中的数据由你定义……但可以只是一个随机字节的数据,或者你可以来建立一个更智能的结构,其中包含有关谁发出信号或其他可能很高兴知道的信息。
更新多个服务员,这有点棘手:所以我会做一些假设来简化事情
这种方法使用计数信号量,与上面类似,只是有一点额外的逻辑:
wait(event)
{
if (semTake(event->csm, timeoutTime) == OK)
{
// got it...
}
else
{
// timeout, report error or something like that....
}
}
你的信号代码会是这样的:
signal(event)
{
for (int x = 0; x < event->numberOfWaiters; x++)
{
semGive(event->csm);
}
}
事件的创建是这样的,记住在这个例子中,服务员的数量是恒定的,并且在事件创建时是已知的。您可以使其动态化,但关键是每次事件将要发生时 numberOfWaiters 必须正确,然后解锁器才能解锁互斥锁。
createEvent(numberOfWaiters)
{
event->numberOfWaiters = numberOfWaiters;
event->csv = semCCreate(SEM_Q_FIFO, 0);
return event;
}
您不能对 numberOfWaiters 抱有幻想:D 我再说一遍:在解锁器解锁互斥锁之前,numberOfWaiters 必须是正确的。要使其动态化(如果需要),您可以添加一个 setNumWaiters(numOfWaiters) 函数,并在解锁器解锁互斥锁之前在 wait_for 函数中调用它,只要它始终正确设置数字即可。
现在最后一个技巧,如上所述,假设是一个任务负责解锁互斥锁,其余的只是等待信号,这意味着只有一个任务会调用上面的 wait_for() 函数,其余任务只需调用 wait(event) 函数。
考虑到这一点,numberOfWaiters 的计算方式如下:
当然,如果你真的需要,你也可以让它变得更复杂,但这很有可能会起作用,因为通常 1 个任务会触发一个事件,但许多任务想知道它是否已完成,这就是它所提供的。
但你的基本流程如下:
init()
{
event->createEvent(3);
}
eventHandler()
{
locker l(mutex);
doEventProcessing();
signal(event);
}
taskA()
{
doOperationThatTriggersAnEvent();
wait_for(mutex);
eventComplete();
}
taskB()
{
doWhateverIWant();
// now I need to know if the event has occurred...
wait(event);
coolNowIKnowThatIsDone();
}
taskC()
{
taskCIsFun();
wait(event);
printf("event done!\n");
}
当我写上面的时候,我觉得所有的 OO 概念都已经死了,但希望你明白,实际上 wait 和 wait_for 应该采用相同的参数,或者不带参数,而是成为同一个类的成员,该类也具有所有他们需要知道的数据......但仍然是它如何工作的概述。
关于c++ - 如何避免 VxWorks 中条件变量中的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19096150/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!