草庐IT

C++异步调用最佳实践

coder 2024-02-21 原文

我正在使用 boost::asio。我写了一个类负责从套接字异步读取。 在我的应用程序中,io_service 可以在一个应用程序运行期间多次停止和启动。 所以我不得不担心服务停止时的内存泄漏。 我得出了两个解决方案:

  1. 请求异步请求的类为函数提供了用于 asio 读取的缓冲区,并负责释放缓冲区。这是一个显而易见的解决方案,但我不喜欢它。将不需要的参数传递给函数看起来真的很奇怪。

  2. 绑定(bind)到回调的智能指针。这里的例子: http://pastebin.com/p8nQ5NFi

现在我正在使用第二种解决方案,但不管我怎么想,我正在发明一个轮子。异步调用中缓冲区清理的常见做法是什么?我的方法有什么隐患吗?

最佳答案

shared_ptr方法相当普遍。然而,而不是通过 shared_ptr作为 bind 的附加参数, 可以传递 shared_ptr作为实例对象代替 this .

boost::shared_ptr< my_class > ptr( this );

boost::asio::async_read( stream, buffer, 
  boost::bind( &my_class::read_handler, ptr, 
     boost::asio::placeholders::error
     boost::asio::placeholders::bytes_transferred ) );

通常,因为实例将通过 shared_ptr 进行管理, 可能在也可能不在 this 的上下文中, 使用 Boost.SmartPointer 的 enable_shared_from_this 是个好主意.当一个类继承自 boost::enable_shared_from_this , 它提供了一个 shared_from_this()返回有效 shared_ptr 的成员函数实例到 this .

class my_class: public boost::enable_shared_from_this< my_class >
{
  void read()
  {
     boost::asio::async_read( stream, buffer, 
       boost::bind( &my_class::read_handler, shared_from_this(), 
          boost::asio::placeholders::error
          boost::asio::placeholders::bytes_transferred ) );
  }
};

boost::shared_ptr< my_class > foo( new my_class() );
foo->read();

在此代码段中,foo.get()foo->shared_from_this()两者都指向同一个实例。这有助于防止难以定位的内存泄漏。例如,在原始示例代码中,内存泄漏发生在Protocol::AsyncReadMessage。如果AsyncReadHandler的复制构造函数在尝试调用时抛出 AsyncReadMessage . Boost.Asio 的 asynchronous TCP daytime server和许多 examples显示 enable_shared_from_this在 Boost.Asio 中使用。为了更深入的了解,this问题具体涉及异步 Boost.Asio 函数和 shared_ptr .


此外,在原始代码中,可能更容易制作Protocol::AsyncHelper。一个模板类,而不是让它成为一个具有模板成员函数的非模板类。这将允许 AsyncHelper接受协议(protocol)、流和处理程序作为构造函数参数,并将它们存储为成员变量。此外,它使 bind调用稍微更容易阅读,因为它减少了需要传递的参数数量,并且由于成员函数不再是模板,因此无需指定它们的完整类型。 Here是一个示例的快速传递。

关于C++异步调用最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11641620/

有关C++异步调用最佳实践的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

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

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

  5. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  6. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  9. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

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

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

随机推荐