草庐IT

c++ - 实时系统的两阶段构建

coder 2024-02-06 原文

我正在开发一个实时系统,并且正在讨论类的设计。
具体来说,我无法决定是否通过使用两阶段构造来构建“重载”类。

一方面,在运行时调用“重载”类的构造函数可能会成为主要瓶颈,这使我免于创建类和分配用户可能不会使用的功能的内存。

另一方面,考虑到当我们尝试访问一个功能的情况时,两阶段构造可能会在执行过程中产生意外,但由于它没有初始化,所以我们不能这样做,突然之间我们需要在使用之前完全构造它。

我的倾向是采用两阶段构造方法。我想听到的是在实时系统上进行两阶段构建的利弊。如果有更好的方法可以解决这一问题。

这里是重类的代码示例的示例(我的类肯定不会那样,但是它展示了我的想法):

 class VeryHeavy {

 private:

    HeavyClass1* p1;
    HeavyClass2* p2;
    HeavyClass3* p3;
    HeavyClass4* p4;
    HeavyClass5* p5;

    int* hugeArray [100000];

    //...//

};

最佳答案

这是AGC,即Apollo制导计算机,在Apollo命令模块和月球模块上均使用。以几乎使阿波罗11号飞机的着陆被擦洗而闻名。就在下降到月球表面的中间,这台计算机因实时错误而崩溃。几次。产生系统错误1201(执行溢出-没有空闲区域)和系统错误1202(执行溢出-没有核心设置)。阿姆斯特朗(Armstrong)和奥尔德林(Aldrin)只看到了数字,在照片右侧看到的UI设备太原始了,无法显示字符串。引导 Controller Steve Bales知道数字的含义(他们在训练时从未见过错误),并且知道系统可以从中恢复。并且通过给予GO来节省着陆,他为此获得了总统自由勋章。

尽管我们可以确定您没有在尝试着陆,但是这很可能是您的问题所要问的问题。术语“实时”曾经在软件工程中定义得很好,但是却被金融业弄糊涂了。在Apollo 11中,这意味着系统对外部事件的最大响应时间具有非常严格的上限。火箭需要一个这样的系统,有时在调整喷嘴时不会太迟,一旦迟到会产生十亿美元的火球。金融业劫持它的意思是一个任意快速的系统,尽管迟到有时不会使该机器蒸发,尽管它使交易损失的可能性更大。他们可能也认为这是一场灾难:)

您使用的内存分配器很重要,问题中也没有定义。我会假定您的程序正在按需分页的虚拟内存操作系统上运行。并不是实时系统的理想环境,而是普遍通用的真正实时操作系统的表现并不理想。

两阶段构造是用于处理初始化失败的技术,难以处理在构造函数中引发的异常,析构函数将无法运行,因此如果您在构造函数中进行分配而未使构造函数足够智能,则可能导致资源泄漏处理一个不幸的事。另一种选择是稍后在成员函数中执行此操作,并根据需要延迟分配。

因此,您担心的是惰性分配会阻碍系统的响应速度。产生系统错误1201。

实际上,这不是按需分页的虚拟内存操作系统(例如Linux或Windows)的主要关注点。这些操作系统上的内存分配器速度很快,它仅分配虚拟内存。这不花任何钱,它是虚拟的。当您真正开始使用分配的内存时,才需要支付实际费用。需求分页的“需求”发挥作用的地方。寻址数组元素将产生页面错误,从而迫使操作系统将寻址的虚拟内存页面映射到RAM中。如果机器没有受到其他压力,并且必须取消映射另一个进程正在使用的页面以获取RAM,则此类页面错误相对便宜,称为“软”页面错误。您希望操作系统能够仅抓取页面并映射它,开销以微秒为单位。

因此,实际上,如果您做对了,并且在分配它时不尝试初始化整个数组,那么您的程序将遭受成千上万的细微开销。每一个小到不会危及实时响应保证的程度。无论您是提前分配内存还是延迟分配内存,都会发生这种情况,因此,无论使用两阶段构造,都无关紧要。

如果您想保证这种情况不会发生,或者想对初始化整个数组时遇到的页面错误 Storm 有弹性,那么您将需要一种非常不同的方法,您需要对页面锁进行锁定。 RAM分配,以便操作系统无法取消映射页面。这总是需要修改OS设置,它通常不允许进程分页锁定大量内存。然后当然也要进行两阶段 build 。

请记住,程序很少知道如何处理分配失败。它们的行为几乎就像异步异常一样,随时可以在程序的几乎任何部分中随时发生。尤其难以与实时需求保持一致,因为由于内存不足而无法对实时事件做出响应的系统当然并不比最新的系统好。这仍然是一个火球;)因此,它本身应该已经是足够的理由,不用理会两阶段构造,只需在程序初始化时分配内存,然后再开始保证实时响应即可。它使程序的编写变得简单得多,失败的几率要低得多。

对于任何具有实时特征的软件,一个非常艰巨的要求是,它不必与其他进程抗衡即可获取操作系统资源。仅将整个机器专用于一个进程是预期的,就像AGC一样,您不再局限于rope memory的36864字和RAM的2048字了。如今,硬件便宜又足够,足以提供这样的保证。

关于c++ - 实时系统的两阶段构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17855859/

有关c++ - 实时系统的两阶段构建的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 在 Ruby 中构建长字符串的简洁方法 - 2

    在编写Ruby(客户端脚本)时,我看到了三种构建更长字符串的方法,包括行尾,所有这些对我来说“闻起来”有点难看。有没有更干净、更好的方法?变量递增。ifrender_quote?quote="NowthatthereistheTec-9,acrappyspraygunfromSouthMiami."quote+="ThisgunisadvertisedasthemostpopularguninAmericancrime.Doyoubelievethatshit?"quote+="Itactuallysaysthatinthelittlebookthatcomeswithit:themo

  3. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  4. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  5. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  6. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  7. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  8. ruby - 使用 rbenv 和 ruby​​-build 构建 ruby​​ 失败,出现 undefined symbol : SSLv2_method - 2

    我正在尝试在配备ARMv7处理器的SynologyDS215j上安装ruby​​2.2.4或2.3.0。我用了optware-ng安装gcc、make、openssl、openssl-dev和zlib。我根据README中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby​​-build插件。.这些是随optware-ng安装的软件包及其版本binutils-2.25.1-1gcc-5.3.0-6gconv-modules-2.21-3glibc-opt-2.21-4libc-dev-2.21-1libgmp-6.0.0a-1libmpc-1.0.2-1libm

  9. ruby - 在没有基准或时间的情况下用 Ruby 测量用户时间或系统时间 - 2

    因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实

  10. ruby - 以毫秒为单位获取当前系统时间 - 2

    在Ruby中,以毫秒为单位获取自纪元(1970)以来的当前系统时间的正确方法是什么?我试过了Time.now.to_i,好像不是我想要的结果。我需要结果显示毫秒并且使用long类型,而不是float或double。 最佳答案 (Time.now.to_f*1000).to_iTime.now.to_f显示包含十进制数字的时间。要获得毫秒数,只需将时间乘以1000。 关于ruby-以毫秒为单位获取当前系统时间,我们在StackOverflow上找到一个类似的问题:

随机推荐