我经常在代码中看到这种模式,将 shared_from_this 作为第一个参数绑定(bind)到成员函数并使用 async_* 函数调度结果。这是另一个问题的示例:
void Connection::Receive()
{
boost::asio::async_read(socket_,boost::asio::buffer(this->read_buffer_),
boost::bind(&Connection::handle_Receive,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
使用 shared_from_this() 而不是 this 的唯一原因是在调用成员函数之前保持对象处于事件状态。但除非在某处有某种 boost 魔法,因为 this 指针的类型是 Connection*,这就是 handle_Receive 可以采用的所有内容,而 smart返回的指针应立即转换为常规指针。如果发生这种情况,则没有任何东西可以使对象保持活力。当然,调用 shared_from_this 时没有指针。
但是,我经常看到这种模式,我不敢相信它会像我认为的那样完全被打破。当操作完成时,是否有一些 Boost 魔术导致 shared_ptr 稍后转换为常规指针?如果是这样,这是否记录在某处?
特别是,它是否在某处记录了共享指针将保持存在直到操作完成?在强指针上调用 get_pointer 然后在返回的指针上调用成员函数是不够的,除非强指针直到成员函数返回才被销毁。
最佳答案
简而言之,boost::bind创建 boost::shared_ptr<Connection> 的拷贝从 shared_from_this() 返回, 和 boost::asio可以创建处理程序的拷贝。处理程序的拷贝将保持事件状态,直到发生以下情况之一:
run() 所在的线程调用。 , run_one() , poll()或 poll_one()成员函数已被调用。io_service被销毁了。io_service::service拥有处理程序的通过 shutdown_service() 关闭.以下是文档的相关摘录:
boost::bind documentation :
The arguments that
bindtakes are copied and held internally by the returned function object.
boost::asio io_service::post :
The
io_serviceguarantees that the handler will only be called in a thread in which therun(),run_one(),poll()orpoll_one()member functions is currently being invoked. [...] Theio_servicewill make a copy of the handler object as required.
boost::asio io_service::~io_service :
Uninvoked handler objects that were scheduled for deferred invocation on the
io_service, or any associated strand, are destroyed.
Where an object's lifetime is tied to the lifetime of a connection (or some other sequence of asynchronous operations), ashared_ptrto the object would be bound into the handlers for all asynchronous operations associated with it. [...] When a single connection ends, all associated asynchronous operations complete. The corresponding handler objects are destroyed, and allshared_ptrreferences to the objects are destroyed.
虽然日期为 (2007),但 Networking Library Proposal for TR2 (Revision 1)源自 Boost.Asio。栏目5.3.2.7. Requirements on asynchronous operations为 async_ 的参数提供了一些详细信息功能:
In this clause, an asynchronous operation is initiated by a function that is named with the prefix
async_. These functions shall be known as initiating functions. [...] The library implementation may make copies of the handler argument, and the original handler argument and all copies are interchangeable.The lifetime of arguments to initiating functions shall be treated as follows:
- If the parameter is declared as a const reference or by-value [...] the implementation may make copies of the argument, and all copies shall be destroyed no later than immediately after invocation of the handler.
[...] Any calls made by the library implementation to functions associated with the initiating function's arguments will be performed such that calls occur in a sequence call1 to calln, where for all i, 1 ≤ i < n, calli precedes call i+1.
因此:
shared_ptr<Connection> 的拷贝,增加 Connection 的引用计数实例,而 handler 的拷贝仍然存在。io_serive::service 时未完成,则会发生这种情况。正在关闭或 io_service被摧毁。在示例中,处理程序的拷贝将被销毁,从而减少 Connection 的引用计数。 ,并可能导致 Connection要销毁的实例。Connection 的引用计数。 ,并可能导致其被破坏。asnyc_ 相关的函数的参数,将按顺序执行,而不是并发执行。这包括 io_handler_deallocate和 io_handler_invoke .这保证了在调用 handler 时不会释放 handler。在 boost::asio 的大部分地区实现时,处理程序被复制或移动到堆栈变量,一旦执行退出声明它的 block ,就允许销毁发生。在示例中,这确保了 Connection 的引用计数在调用 handler 期间将至少为 1。关于c++ - boost async_* 函数和 shared_ptr 的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11356742/
这似乎应该有一个直截了当的答案,但在Google上花了很多时间,所以我找不到它。这可能是缺少正确关键字的情况。在我的RoR应用程序中,我有几个模型共享一种特定类型的字符串属性,该属性具有特殊验证和其他功能。我能想到的最接近的类似示例是表示URL的字符串。这会导致模型中出现大量重复(甚至单元测试中会出现更多重复),但我不确定如何让它更DRY。我能想到几个可能的方向...按照“validates_url_format_of”插件,但这只会让验证干给这个特殊的字符串它自己的模型,但这看起来很像重溶液为这个特殊的字符串创建一个ruby类,但是我如何得到ActiveRecord关联这个类模型
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我正在使用RubyonRails3.2.2,我想从我的模型/类中“提取”一些方法。也就是说,在不止一个类/模型中,我有一些方法(注意:方法与用户授权相关,并被命名为“CRUD方式”),这些方法实际上是相同的;所以我认为DRY方法是将这些方法放在“共享”模块或类似的东西中。实现该目标的常见且正确的方法是什么?例如,我应该将“共享”代码放在哪里(在哪些目录和文件中)?如何在我的类/模型中包含提到的方法?你有什么建议?注意:我正在寻找“RubyonRails制作东西的方式”。 最佳答案 一种流行的方法是使用ActiveSupport关注点
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
如何将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.你能做的最好的事情是:
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。