有没有std :: shared_ptr的非primefaces等价物? 为什么在<内存>中没有一个?
这是两个部分的问题,所有关于std::shared_ptr
的primefaces性:
1.据我所知, std::shared_ptr
是<memory>
中唯一的智能指针。 我想知道是否有一个非primefaces版本的std::shared_ptr
可用(我看不到在<memory>
任何东西,所以我也打开了标准以外的build议,如在Boost中的那些)。 我知道boost::shared_ptr
也是primefaces的(如果BOOST_SP_DISABLE_THREADS
没有定义),但也许有另一种select? 我正在寻找具有与std::shared_ptr
相同的语义,但没有primefaces性的东西。
2.我明白为什么std::shared_ptr
是primefaces的; 这有点不错 但是,对于每一种情况都不是很好,C ++在历史上的口号是“只为你使用的东西付钱”。 如果我不使用多个线程,或者如果我使用多个线程,但不是在线程之间共享指针所有权,则primefaces智能指针是矫枉过正的。 我的第二个问题是为什么不是在C ++ 11中提供的std::shared_ptr
的非primefaces版本 ? (假设有一个为什么 )(如果答案只是“一个非primefaces版本从来没有考虑过”或“没有人要求过一个非primefaces版本”这很好!)。
在问题#2中,我想知道是否有人曾经提出shared_ptr
的非primefaces版本(要么提升或标准委员会)(不是取代shared_ptr
的primefaces版本,而是与它共存),它被击落出于特定原因。
1.我想知道是否有可用的std :: shared_ptr的非primefaces版本
不是由标准提供的。 可能有一个由“第三方”图书馆提供的。 事实上,在C ++ 11之前,在Boost之前,似乎每个人都编写了自己的引用计数智能指针(包括我自己)。
2.我的第二个问题是为什么不是C ++ 11中提供的std :: shared_ptr的非primefaces版本?
这个问题在2010年的拉珀斯维尔会议上进行了讨论。这个问题由瑞士的国家机构意见20介绍。 辩论双方都有强烈的论据,包括你提出的问题。 但是,在讨论结束时,投票反对(但不一致)反对添加shared_ptr
非同步(非primefaces)版本。
反对的论点包括:
-
使用未同步的shared_ptr编写的代码最终可能会被用在线程代码中,从而导致难以debugging的问题而不会出现警告。
-
拥有一个“通用”shared_ptr,这是“参考计数”stream量的“单向”,具有以下好处:从最初的提议 :
具有相同的对象types,而不考虑使用的function,极大地促进了库(包括第三方库)之间的互操作性。
-
primefaces的成本虽然不是零,但并不是太大。 通过使用不需要使用primefaces操作的移动构build和移动分配来减轻成本。 这种操作通常用于
vector<shared_ptr<T>>
擦除和插入。 -
如果这真的是他们想要做的事情,那么什么都不能禁止人们编写自己的非primefaces引用计数智能指针。
拉珀斯维尔LWG当天的最后一句话是:
拒绝CH 20.目前没有达成一致的意见。
Howard已经很好地回答了这个问题,Nicol对于使用单一标准共享指针types的好处提出了一些好的build议,而不是很多不兼容的指针types。
虽然我完全同意委员会的决定,但我确实认为在特殊情况下使用不同步的shared_ptr
types会有一些好处,所以我已经调查了几次这个话题。
如果我不使用多个线程,或者如果我使用多个线程,但不是在线程之间共享指针所有权,则primefaces智能指针是矫枉过正的。
有了GCC,当你的程序不使用multithreading时,shared_ptr不会使用primefaces操作符作为refcount。 这是通过使用包装函数更新引用计数来实现的,这些函数检测程序是否是multithreading的(在GNU / Linux上,这是通过检测程序是否链接到libpthread.so
)并相应地分派到primefaces操作或非primefaces操作。
我在很多年前就意识到,因为GCC的shared_ptr<T>
是以__shared_ptr<T, _LockPolicy>
基类的forms实现的,即使在multithreading代码中也可以使用带有单线程锁策略的基类,通过显式使用__shared_ptr<T, __gnu_cxx::_S_single>
。 不幸的是,因为这不是一个预期的用例,所以在GCC 4.9之前它并没有达到最佳工作状态,而且有些操作仍然使用包装函数,因此即使明确地请求了_S_single
策略也被派发到primefaces操作。 请参阅http://gcc.gnu.org/ml/libstdc++/2007-10/msg00180.html上的第(2)点以获取更多细节和GCC补丁,以便即使在multithreading应用程序中也可以使用非primefaces实现。; 我坐在那个补丁上好几年了,但是我终于把它交给了GCC 4.9,它允许你使用这样的别名模板来定义一个不是线程安全但是稍微快一点的共享指针types:
template<typename T> using shared_ptr_unsynchronized = std::__shared_ptr<T, __gnu_cxx::_S_single>;
这种types不能与std::shared_ptr<T>
互操作,只有在确保shared_ptr_unsynchronized
对象永远不会在没有额外的用户提供的同步的情况下在线程之间共享的情况下使用才是安全的。
这当然是完全不可移植的,但有时候也没关系。 有了正确的预处理器,如果shared_ptr_unsynchronized<T>
是shared_ptr_unsynchronized<T>
的别名,那么对于其他实现,您的代码仍然可以正常工作。
如果你在4.9之前使用GCC,你可以通过在自己的代码中添加_Sp_counted_base<_S_single>
显式的特化来确保没有人实例化__shared_ptr<T, _S_single>
而不包括特殊化,以避免ODR违例。 std
types的这种特殊化在技术上是未定义的,但是在实践中会起作用,因为在这种情况下,我为GCC添加专门化或者将它们添加到自己的代码中没有区别。
我的第二个问题是为什么不是在C ++ 11中提供的std :: shared_ptr的primefaces版本? (假设有一个为什么)。
人们可以很容易地问为什么没有一个侵入性的指针,或任何其他可能的变化共享指针可能有。
从Boost传递的shared_ptr的devise一直是创build一个智能指针的最低标准通用语言。 一般来说,你可以把它从墙上拉下来使用。 这是通常在各种各样的应用程序中使用的东西。 你可以把它放在一个界面中,而好的人会愿意使用它。
线程只会在未来变得更普遍。 事实上,随着时间的推移,线程化通常将是实现性能的主要手段之一。 要求基本的智能指针尽可能less地支持线程,这便于实现。
将六个智能指针之间的细微差异倒入标准,甚至更糟糕的政策智能指针,将是可怕的。 每个人都会select他们最喜欢的指针,并且放弃所有其他人。 没有人能够与其他人沟通。 这就像现在的C ++string一样,每个人都有自己的types。 更糟糕的是,因为与string的互操作比智能指针类之间的互操作要容易得多。
推动,并延长委员会,select了一个特定的智能指针使用。 它提供了一个很好的特点平衡,在实践中被广泛和常用。
std::vector
在某些angular落案例中与裸数组相比也有一些低效率。 它有一些限制; 一些用途确实想要对vector
的大小有一个严格的限制,而不使用投掷分配器。 然而,委员会并没有将vector
devise成为每个人的一切。 它被devise成对大多数应用来说是一个很好的默认设置。 那些不能工作的人可以写一个满足他们需求的select。
正如你可以为一个智能指针,如果shared_ptr的primefaces性是一个负担。 再说一遍,也可以考虑不要太复制它们。
我正在准备讨论shared_ptr的工作。 我一直在使用一个修改后的boost shared_ptr,避免使用单独的malloc(比如make_shared可以做的事情)和一个像上面提到的shared_ptr_unsynchronized一样的locking策略的模板参数。 我正在使用该程序
http://flyingfrogblog.blogspot.hk/2011/01/boosts-sharedptr-up-to-10-slower-than.html
作为一个testing,在清理了不必要的shared_ptr拷贝之后。 程序只使用主线程,并显示testing参数。 testing环境是一个运行linuxmint 14的笔记本。下面是几秒钟的时间:
testing运行安装boost(1.49)std与make_shared修改提升 mt-unsafe(11)11.9 9 / 11.5(-pthread on)8.4 primefaces(11)13.6 12.4 13.0 不安全(12)113.5 85.8 / 108.9(-pthread on)81.5 primefaces(12)126.0 109.1 123.6
只有'std'版本使用-std = cxx11,而-pthread可能会在g ++ __shared_ptr类中切换lock_policy。
从这些数字中,我看到primefaces指令对代码优化的影响。 testing用例不使用任何C ++容器,但是如果对象不需要线程保护,则vector<shared_ptr<some_small_POD>>
可能会受到影响。 增加的可能性较小,因为额外的malloc限制了内联和代码优化的数量。
我还没有find一台具有足够内核的机器来压力testingprimefaces指令的可伸缩性,但只有在必要时才使用std :: shared_ptr可能会更好。