我见过有些人讨厌recursive_mutex:
http://www.zaval.org/resources/library/butenhof1.html
但是在考虑如何实现一个线程安全的类(互斥保护)时,我觉得很难证明每个应该受互斥保护的方法都是互斥保护的,并且互斥锁最多被锁定一次.
因此,对于面向对象的设计,应该std::recursive_mutex是默认的并且std::mutex在一般情况下被视为性能优化,除非它仅在一个地方使用(仅保护一个资源)?
为了说清楚,我说的是一个私人非静态互斥体.因此每个类实例只有一个互斥锁.
在每个公共方法的开头:
{
std::scoped_lock<std::recursive_mutex> sl;
Run Code Online (Sandbox Code Playgroud) 在JavaScript中,您可以使用某种extend函数组合对象.
例如,我可能有一个observable是公开一组公共方法类(get,push,set,increment,get,等)
在这种情况下可观察到的也恰好是一个EventEmitter所以它也公开了一组新的,公共的方法(emit,on,removeListener等)
这两个类都有内部下划线前缀属性,用于存储状态.eventemitter用于_events存储事件处理程序和可观察的用途_state以及_id存储状态和id.
现在,当我使用像这样的对象组合创建模型时
var Model = extend({}, Observable, {
constructor: function () {
// Oops, I was supposed to know Observable uses the _state name already
this._state = { ... }
},
someMethod: function () { ... }
})
Run Code Online (Sandbox Code Playgroud)
这会导致问题,因为Observable已经使用了_state内部属性,现在存在名称冲突.
我认为只是"必须知道"哪些对象依赖于mixin的内部属性才能安全地工作.
如何避免混合使用相同内部属性名称的两个对象?
理想情况下,这将通过ES6私有名称解决,但我们还不能这样做,我们无法模仿它们而不会失去性能.除非您能提供没有大的性能损失的ES6名称仿真,否则我对这些解决方案不感兴趣.
另一种方法是使用闭包, …
经常我会遇到类似的代码
/*initializer list of some class*/:m_member(some_param,/* --> */ *this)
Run Code Online (Sandbox Code Playgroud)
这样做的原因是m_member可以从包含它的类中调用成员函数... aka
//code in class that is m_member instance of
m_parent->some_function();
Run Code Online (Sandbox Code Playgroud)
我个人不喜欢它,因为我认为它是可怜的设计("亲爱的孩子,你知道你在做什么对你的课程封装"),但我想知道一般这种行为不好,如果是这样,如何避免这种设计.
编辑:请不要把重点放在initalizer列表中,让我们说它是在ctor体内.
我正在尝试了解Python中@property装饰器的实用程序。具体来说,我使用如下属性设置了一个类:
class A(object):
def __init__(self, x):
self._x = x
@property
def x(self):
return self._x
@x.setter
def x(self, new_x):
self._x = new_x
Run Code Online (Sandbox Code Playgroud)
而且我还建立了一个没有提供相同功能的属性的类:
class B(object):
def __init__(self, x):
self._x = x
Run Code Online (Sandbox Code Playgroud)
我创建每个实例:
a = A(10)
b = B(10)
Run Code Online (Sandbox Code Playgroud)
在iPython中运行%timeit会产生以下结果
%timeit a.x
%timeit b._x
Run Code Online (Sandbox Code Playgroud)
1000000次循环,每循环3:213 ns的最佳时间
10000000次循环,最佳3:每个循环67.9 ns
%timeit a.x = 15
%timeit b._x = 15
Run Code Online (Sandbox Code Playgroud)
1000000个循环,每个循环最好3:257 ns
10000000次循环,每循环3:89.7 ns最佳
显然,如果您要以很高的频率与该对象交谈,则@property和@setter装饰器会逊色。我的问题就是,为什么要使用它?我想听听人们可能拥有的这些装饰器的用例。谢谢。
在他们的公共API中有许多java标准和第三方库,有写入或读取的方法Stream.一个例子是javax.imageio.ImageIO.write()将OutputStream处理过的图像的内容写入其中.另一个例子是iText pdf处理库,它将OutputStream生成的pdf写入其中.第三个例子是AmazonS3 Java API,InputStream它将读取它并在S3存储中创建文件.
当你想要结合其中两个时,问题就会出现问题.例如,我有一个图像BufferedImage,我必须用它ImageIO.write来推动结果OutputStream.但是,正如S3所要求的那样,没有直接的方法将其推送到Amazon S3 InputStream.
有很多方法可以解决这个问题,但这个问题的主题是使用ByteArrayOutputStream.
后面的想法ByteArrayOutputStream是使用一个包含在其中的中间字节数组,Input/Output Stream以便想要写入输出流的人将写入数组并且想要读取的人将读取数组.
我不知道为什么ByteArrayOutputStream不复制它就不允许任何对字节数组的访问,例如,提供一个InputStream可以直接访问它的字节数组.访问它的唯一方法是调用toByteArray(),它将复制内部数组(标准数组).这意味着,在我的图片示例中,我将在内存中拥有三个图像副本:
BufferedImage,array的OutputStream并toByteArray()我制作的副本,所以我可以创建
InputStream.这个设计如何合理?
getInputStream(),实施保持隐藏. ByteArrayOutputStream不管怎样都不适合多线程访问,所以这不可能. 此外,ByteArrayOutputStreamApache的commons-io库(具有不同的内部实现)提供了第二种风格.但两者都具有完全相同的公共接口,无法在不复制的情况下访问字节数组.
c++ ×2
c++11 ×1
composition ×1
io ×1
java ×1
javascript ×1
mutex ×1
performance ×1
properties ×1
python ×1