如果我有一个非常不可变的类型(所有成员都是只读的,如果它们是引用类型成员,那么它们也引用了非常不可变的对象).
我想在类型上实现一个惰性初始化属性,如下所示:
private ReadOnlyCollection<SomeImmutableType> m_PropName = null;
public ReadOnlyCollection<SomeImmutableType> PropName
{
get
{
if(null == m_PropName)
{
ReadOnlyCollection<SomeImmutableType> temp = /* do lazy init */;
m_PropName = temp;
}
return m_PropName;
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知:
m_PropName = temp;
Run Code Online (Sandbox Code Playgroud)
......是线程安全的.我并不担心两个线程同时竞争初始化,因为它很少见,从逻辑角度来看两个结果都是相同的,如果我没有,我宁愿不使用锁至.
这会有用吗?优缺点都有什么?
编辑: 谢谢你的回答.我可能会继续使用锁.但是,我很惊讶没有人提出编译器意识到临时变量是不必要的可能性,只是直接分配给m_PropName.如果是这种情况,则读取线程可能会读取尚未完成构造的对象.编译器是否会阻止这种情况?
(答案似乎表明运行时不会允许这种情况发生.)
编辑: 所以我决定使用由Joe Duffy撰写的这篇文章启发的Interlocked CompareExchange方法.
基本上:
private ReadOnlyCollection<SomeImmutableType> m_PropName = null;
public ReadOnlyCollection<SomeImmutableType> PropName
{
get
{
if(null == m_PropName)
{
ReadOnlyCollection<SomeImmutableType> temp = /* do lazy init */;
System.Threading.Interlocked(ref m_PropName, temp, null);
}
return …Run Code Online (Sandbox Code Playgroud) 我有一堆线程正在彼此进行大量的沟通.我希望这是免费的.
对于每个线程,我想拥有一个邮箱,其他线程可以向其发送消息(但只有所有者可以删除消息).这是一个多生产者单一消费者的情况.我可以在无锁/高性能的事情上做到这一点吗?(这是一个巨大模拟的内循环.)
在我尝试开发一个线程安全的C++弱指针模板类时,我需要检查一个指示对象仍处于活动状态的标志,如果是,则增加对象的引用计数,我需要以原子方式执行这两个步骤.
我知道编译器提供的内在函数的存在,例如_InterlockedCompareExchange()和_InterlockedIncrement().但我想要的是一个interlockedCompareIncrement()函数,有没有一种有效的方法来使用其他原语来模拟这个内在函数,至少在Windows x86平台上?
是否存在" 无锁FIFO队列的optmistic方法"算法的 C++实现(源代码)?
我已经看到了堆栈的一些无锁实现...我的问题是关于可见性,而不是原子性.例如,无锁堆栈的元素(不是指针)必须至多为64位?我是这么认为的,因为你无法保证知名度.真实示例:可以安全地插入此结构并从无锁容器中删除
struct person
{
string name;
uint32_t age;
}
Run Code Online (Sandbox Code Playgroud)
编辑:有些人对这个问题感到困惑.为了解释一下:如果作家把人推到堆栈上,读者就会得到它,是否保证读者看到(记忆可见性)正确的人的内容.
我正在进行我的Clojure任务(在4clojure.com上解决了大约80个问题)并继续阅读和编码并试图"得到它".
现在我对Clojure被设计为"无锁并发"感到困惑.我非常了解死锁(例如:"我编写了糟糕的Java代码,最终导致死锁",而不是"我是并发专家").我也读过这个:
我意识到Clojure程序不会陷入僵局.
但是我有点困惑:通过在引擎盖下无锁算法实现或使用可能的"死锁"算法实现了这样的壮举,但使用正确的实现保证永远不会死锁(这将以某种方式"隐藏"给Clojure程序员)?
最近讨论过关于无锁算法的黑客新闻:
http://news.ycombinator.com/item?id=4103921
在1024cores.net上引用以下"无锁算法"页面:
http://www.1024cores.net/home/lock-free-algorithms
我不明白这篇文章与Clojure下的并发工作方式之间的关系.
它让我完全糊涂了:当我在Clojure中开发并发程序时,它是否意味着"锁定和无锁算法"对我来说不是问题?
我刚刚看过Herb Sutter的演讲:C++和2012年之后:Herb Sutter - 原子<>武器,2 of 2
他在std :: shared_ptr析构函数的实现中显示了错误:
if( control_block_ptr->refs.fetch_sub(1, memory_order_relaxed ) == 0 )
delete control_block_ptr; // B
Run Code Online (Sandbox Code Playgroud)
他说,由于memory_order_relaxed,删除可以放在fetch_sub之前.
在1:25:18 - 释放不保持在B线下面,它应该在哪里
怎么可能?在关系之前发生 - 之前/顺序 - 因为它们都在单线程中.我可能错了,但fetch_sub和delete之间也存在一个依赖关系.
如果他是对的,哪些ISO项目支持?
是否有一个库实现用C编写的无锁算法(队列,链表和其他)(不是用C++)?我看过像英特尔这样的库,但是我想使用通用库,至少比英特尔库更通用.
在一些关于算法的文章中,有些使用了这个词lockfree,有些则使用了lockless.lockless和之间有什么区别lockfree?谢谢!
更新
http://www.intel.com/content/dam/www/public/us/en/documents/guides/intel-dpdk-programmers-guide.pdf
第5.2节 - "Linux*中的无锁环缓冲区",这是使用"无锁"一词的一个例子
我正在寻找一种无锁的方式来Async在F#中的两个s 之间发出信号.我有两个尾递归async函数,我想要一个产生,直到另一个信号发出,然后继续下一个递归.我可以使用一个事件,但看起来.NET事件在内部使用锁.到目前为止,我发现的唯一解决方案是使用来自ntdll.dll的键控事件,但我更喜欢不需要直接引用特定于平台的DLL的解决方案.有什么方法可以使用System.Threading.Interlocked或其他.NET技术来实现这一目标吗?
这是我想要实现的一个简单示例:
let rec loop1 () =
async {
// do work
// somehow signal loop2
return! loop1 ()
}
let rec loop2 state =
async {
// wait for signal from loop1
// do work
return! loop2 state // This would actually be a new state, not the old state
}
Run Code Online (Sandbox Code Playgroud) lock-free ×10
c++ ×3
lockless ×2
.net ×1
algorithm ×1
atomic ×1
c ×1
c# ×1
c++11 ×1
clojure ×1
concurrency ×1
f# ×1
fifo ×1
immutability ×1
lazy-loading ×1
locking ×1
memory-model ×1
message ×1
queue ×1
visibility ×1