对《原子对象模式》一文的补充

对于多线程程序,我已经习惯于使用 原子对象模式(http://blog.csdn.net/skyMountain/archive/2006/10/04/1320443.aspx)来降低死锁的风险。

但最近一个项目中,使用了原子对象封装了所有多线程访问的资源,系统竟然死锁了,而且锁住的地方恰好是原子对象内部。经过思考,发现此前我们对原子模式的理解有误,以为只要每个对象的公开接口是线程安全的,就可以算是原子对象了,其实还有一个条件:在公开接口中,不能锁定其它公共资源。它可以使用其它原子对象,但使用前不能加锁。不能锁定公共资源,只能锁定内部资源:否则就不是原子对象了。

因此:

1、一般来说,应当想办法禁止原子对象之间的相互调用。

2、如果无法避免1,应当保证原子对象内部资源在锁住的时候不调用其它原子对象的接口。
这一点往往不容易做到,有的时候甚至我们不得不为此付出一定的代价。

3、如果无法避免2,那么应当保证原子对象之间的调用图是一棵单向的树,而不能是一张有回路的网。
只要避开了循环调用,这个系统仍然还是线程安全、无死锁的。

4、原子对象一个很容易被遗忘加锁的地方是析构函数。
原子对象正在删除的时候,其公开函数被其它线程调用了,那么系统很容易崩溃。必须仔细设计避免这一点。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 RDKit 中,创建原子对象的最简单方法是使用 `Chem.Atom()` 函数。当你使用 `Chem.Atom()` 函数时,RDKit 会自动为原子对象设置一些默认值,例如原子序数、原子符号和坐标等。 以下是一个示例代码,展示了如何使用 `Chem.Atom()` 函数创建原子对象,并设置原子的化学元素和坐标: ```python from rdkit import Chem # 创建一个空的分子对象 mol = Chem.Mol() # 创建原子对象 C atom_C = Chem.Atom("C") atom_C.SetAtomicNum(6) # 设置原子序数 atom_C.SetFormalCharge(0) # 设置离子电荷 atom_C.SetHybridization(Chem.rdchem.HybridizationType.SP3) # 设置杂化轨道类型 atom_C.SetNoImplicit(True) # 设置隐式氢原子数 # 创建原子对象 H atom_H = Chem.Atom("H") atom_H.SetAtomicNum(1) atom_H.SetFormalCharge(0) # 将原子添加到分子中 mol.AddAtom(atom_C) mol.AddAtom(atom_H) # 设置原子坐标 atom_C.SetCoordRef((0.0, 0.0, 0.0)) atom_H.SetCoordRef((1.0, 0.0, 0.0)) ``` 在上面的代码中,我们首先使用 `Chem.Mol()` 函数创建一个空的分子对象 `mol`。然后,我们使用 `Chem.Atom()` 函数创建两个原子对象 `atom_C` 和 `atom_H`,并设置它们的化学元素、原子序数、杂化轨道类型等属性。接着,我们将原子对象添加到分子中,并且使用 `SetCoordRef()` 方法设置原子的坐标。 需要注意的是,上面的代码中我们手动为原子对象设置了化学元素、原子序数和坐标等属性。在实际应用中,你可能需要根据具体的需求,设置不同的原子属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值