- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我是一名嵌入式程序员,尝试使用 Visual Studio 2010 和 MingW(作为两个独立的构建环境)在 Win32 环境中模拟实时抢占式调度程序。我对 Win32 调度环境非常熟悉,并且在我尝试做的事情上遇到了麻烦。我并不是要实现实时行为——只是为了让模拟任务以与在真实目标硬件上相同的顺序和顺序运行。
被模拟的实时调度程序有一个简单的目标 - 始终执行能够运行的最高优先级任务(线程)。一旦任务变得能够运行 - 如果它的优先级高于当前正在运行的任务,它必须抢占当前正在运行的任务。由于正在等待的外部事件或超时/阻塞时间/ sleep 时间到期,任务可以运行 - 带有生成时基的滴答中断。
除了这种抢占行为之外,任务可以让出或自愿放弃其时间片,因为它正在执行 sleep 或等待类型的功能。
我通过为正在模拟的实时调度程序创建的每个任务创建一个低优先级 Win32 线程来模拟这一点(该线程有效地执行调度程序将在真实嵌入式目标上执行的上下文切换),一个中等优先级的 Win32 线程作为伪中断处理程序(处理模拟的滴答中断并产生使用 Win32 事件对象向其发出信号的请求),以及一个更高优先级的 Win32 线程来模拟生成滴答中断的外设。
当伪中断处理程序确定应该发生任务切换时,它使用 SuspendThread() 挂起当前正在执行的线程,并使用 ResumeThread() 恢复执行新选择任务的线程。在可能创建的许多任务及其相关联的 Win32 线程中,只有一个管理该任务的线程在任何时候都将脱离挂起状态。
重要的是挂起的线程在调用 SuspendThread() 时立即挂起,并且伪中断处理线程在通知它中断挂起的事件发出信号时立即执行 - 但这不是我看到的行为。
作为我已经解决的一个示例问题:当任务/线程产生时,yield 事件被锁定在一个变量中,并且中断处理线程被发出信号,因为存在需要处理的伪中断(yield)。现在在我习惯于编程的实时系统中,我希望中断处理线程在收到信号后立即执行,因为它比发出信号的线程具有更高的优先级。我在 Win32 环境中看到的是,发出信号的线程在被挂起之前会持续一段时间 - 要么是因为在发出信号的更高优先级线程开始执行之前需要一些时间,要么是因为挂起需要一些时间实际停止运行的任务 - 我不确定是哪个。在任何情况下,通过在向 Win32 中断处理线程发出信号后在信号量上阻塞信号量,并让中断处理 Win32 线程在完成其功能(握手)后解除对线程的阻塞,这可以很容易地纠正。有效地使用线程同步来强制调度模式满足我的需要。为此,我正在使用 SignalObjectAndWait()。
使用这种技术,当被模拟的实时调度程序在合作模式下运行时,模拟工作完美 - 但不是(根据需要)在抢占模式下。
抢占式任务切换的问题我猜是一样的,任务在被告知挂起之后会继续执行一段时间,然后才真正停止运行,所以当运行的线程时,系统不能保证保持一致状态任务暂停。但是在抢占式情况下,因为任务不知道它何时会发生,所以不能使用使用信号量来防止 Win32 thead 继续直到下一次恢复的相同技术。
有没有人把这篇文章写到这么远——抱歉它的长度!
我的问题是:
最佳答案
如果您需要自己进行调度,那么您可以考虑使用 fibers而不是线程。纤程就像线程,因为它们是单独的可执行代码块,但是纤程可以在用户代码中调度,而线程仅由操作系统调度。单个线程可以托管和管理多个纤程的调度,纤程甚至可以相互调度。
关于c - 根据优先级强制 Win32 线程调度到定义的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4218437/
在complier.h中有一个宏定义如下: # define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) 但是这里我有一个问题,就是哪里
curl_easy_setopt 的选项在哪里?定义?我试图寻找 CURLOPT_VERBOSE 和其他一些整数值,但这些似乎没有在 curl.h 中明确定义。 最佳答案 第 792 行: #ifde
我确实有一个如下所示的类(class): //.h file class __declspec(dllimport) MyClass { public: //stuff pri
作者: zhuwenzhuang, 2024.05.08. 阅读前假设读者熟悉数据库使用,了解 SQL 的语法和关系算子的大概含义, 能通过 EXPLAIN 命令查看数据库执行计划. 0 前言
我似乎无法找到是否可以声明一个 header 对象以便在响应 header 中重用它,有一些示例定义了响应模式的对象,但它不会转置为响应 header 。我只设法制作了一个可重用的响应对象,如下所示:
css 选择器 * + * 实际上是什么意思?当您执行检查元素时,您可以在谷歌浏览器的控制台中看到它。在我看来,这似乎是对 "Every second child"应用一种风格,但仍然想确定。谁能帮我
我试图弄清楚基本的IO Haskell 函数是定义好的,所以我使用了this reference我到了putChar函数定义: putChar :: Char -> IO () putChar
我得到了一个自动生成的文件,该文件定义了程序集属性,我正在尝试理解内容。 [assembly: global::System.Runtime.Versioning.TargetFrameworkAtt
This文档演示了如何检查变量是否先前已在 gnuplot 脚本中定义。 文档中的示例: a = 10 if (exists("a")) print "a is defined" if (!exist
好吧,这是一个相当基本的问题:我正在关注 SICP 视频,我对 define、let 和 之间的区别有点困惑设置!. 1) 根据 Sussman 在视频中的说法,define 只允许为变量附加一个值一
我一直在尝试定义一个包含只能具有以下三个值之一的字段的 XSD: 绿色 红色 蓝色 本质上,我想在架构级别定义严格的枚举。 我的第一次尝试似乎是错误的,我不确定修复它的“正确”方法。
有人可以定义“POCO”到底是什么意思吗?我越来越频繁地遇到这个术语,我想知道它是否仅与普通类有关还是意味着更多? 最佳答案 “普通旧式 C# 对象” 只是一个普通的类,没有描述基础结构问题或域对象不
在我经常看到的一些django模型中 myfield = models.CharField(_('myfield')) class_name = models.CharField(_('Type'),
每当 BOOL 数据类型不容易预定义时,我都会使用以下定义进行 boolean 运算, typedef unsigned char BOOL; (由于内存使用)。 我意识到出于性能原因,使用本地总线宽
l_ABC_BEANVector = utilRemote.fnGetVector("ABC_COVBEANVector"); 编码的含义是什么?任何帮助,我真的很感激。谢谢 最佳答案 唯一可以肯定地
我正在使用 javacc 开发一个项目,我遇到问题并需要一些帮助,我的文件中有这样的内容: STRING COPYRIGHT (C) 2003, 2004 SYNOPSYS, INC.; 我为单词 S
我想弄清楚基本的 IO定义了 Haskell 函数,所以我使用了 this reference然后我到了 putChar函数定义: putChar :: Char -> IO () putCha
我在具体类中使用 @property 定义 getter 时遇到问题。这是Python代码: from abc import ABCMeta, abstractproperty class abstr
我正在为大学用 C 语言编写一个小游戏,但我陷入了困境。我(在头文件中)有这个结构: typedef struct{ game_element field[MAX_ROWS][MAX_COLU
我一直在 .l 文件中创建标记定义。由于数据集数量庞大,它变得有点乏味。有没有办法读取文件中的所有单词,例如包含所有名词的 noun.txt 并给所有名词一个标记。 基本上,我想自动化这部分: %%
我是一名优秀的程序员,十分优秀!