问一下有关锁的问题
tomqyp
2007-10-10
插队请教个相关问题:)
关于Lock-Free中用到的CAS原语,在现在的多核处理器上的实现也是线程安全的吗 会不会有一个核心上的CAS指今还没执行完,其它核心已经多次改写了CAS操作的内存 |
|
oldrev
2007-10-10
ahadf 写道 oldrev 写道 老实说,没有用 scope(exit) 的清晰,而且多了一个调用
见仁见智吧,我个人很喜欢这种风格的。 看D发展的情况了,如果实现了 struct 的 ctor/dtor 话,ScopeLock lock(mutex) 就顺水推舟了 |
|
Colorful
2007-10-11
tomqyp 写道 插队请教个相关问题:)
关于Lock-Free中用到的CAS原语,在现在的多核处理器上的实现也是线程安全的吗 会不会有一个核心上的CAS指今还没执行完,其它核心已经多次改写了CAS操作的内存 这个是可能的。 CAS语义上有漏洞。 考虑以下情况:当第一次读取V的A值。此时, 内存V的值变为B值, 然后在未执行CAS前, 又变回了A值. |
|
tomqyp
2007-10-11
谢谢 ;P
|
|
redsea
2007-10-11
Colorful 写道 tomqyp 写道 插队请教个相关问题:)
关于Lock-Free中用到的CAS原语,在现在的多核处理器上的实现也是线程安全的吗 会不会有一个核心上的CAS指今还没执行完,其它核心已经多次改写了CAS操作的内存 这个是可能的。 CAS语义上有漏洞。 考虑以下情况:当第一次读取V的A值。此时, 内存V的值变为B值, 然后在未执行CAS前, 又变回了A值. CAS 对应的CPU指令是选择 atomic 指令, 不会发生这个情形. 因此不是所有的指令都可以用来做这样操作的. |
|
redsea
2007-10-11
那还不如用一个 scope 类来做呢
final scope class Lock(T) { T lock_; this(t lock) { lock_ = lock; lock.lock(); } ~this() { lock.unlock(); } } alias Lock!(Mutex) LMutex; 用的时候 auto l=new LMutex(somemutex); ... 其他代码 ... ahadf 写道 想了一下,可以仿照ruby来搞:
void scope_lock(T)(ref T t,void delegate() fn) { t.lock(); scope(exit) t.unlock(); fn(); } scope_lock(mutex, { do_something(); } ); 有scope就是好,比ruby,java之类用异常好多了。 |
|
redsea
2007-10-11
Windows Critical Section 我记得是一个好东西啊, 原理似乎是, 先用 spin_lock 尝试一小段时间, 如果成功了, 就避免了线程切换; 如果这一小段时间没有成功, 那么用会睡眠的方式继续等待.
Windows 的 event 才是一个坏东西, event 相关的线程, 多半会使用共享的存储区, 但是event 将通知机制和保护机制分开两个东西, 代码一不小心就会引发危险, 产生几率小, 很难查找的同步错误. 有文章比较过 event 和 unix 的 condition 机制的, 并且证明了现在很多使用event 的代码都有隐患. 具体详情我忘掉了. 所以 C++ boost 里面也没有加入 event, 而是用 event, semaphore 在 windows 下面模拟了一个 condition. 这里说了 boost.thread 是特意不支持 windows event 的, 但是没有具体举例. http://www.boost.org/doc/html/thread/rationale.html#thread.rationale.events 好久没有搞 Windows 开发了 ;) unix 的东西熟悉了感觉比 Windows 更好. Colorful 写道 要顾虑Win上的多线程开发,这些玩意是不能避免的。因为Critical Section在线程大于一个阙值后,性能会严重下降,因为线程竞争会导致有些线程饥饿。这时候就必须采用其他的同步方式了,比如自旋锁之类。 此外,Linux也应该有相对应的机制吧。 我听说Linux平台上有条件变量的锁机制,但是WinXP上却没有,Vista里有。 完了,我这辈子算是陷在Windows的泥潭里了。 |
|
redsea
2007-10-11
Windows 的 api 很丰富, 但是设计 api 的时候, 似乎并没有明确的理论指导思想应该怎么弄.
posix 选择的 api, 倒是经过很多大师级人物的专门研究, 同步这块, 也是有理论支持的, api 不多, 但是够用并且安全. |
|
ahadf
2007-10-11
redsea 写道 那还不如用一个 scope 类来做呢
final scope class Lock(T) { T lock_; this(t lock) { lock_ = lock; lock.lock(); } ~this() { lock.unlock(); } } alias Lock!(Mutex) LMutex; 用的时候 auto l=new LMutex(somemutex); ... 其他代码 ... ahadf 写道 想了一下,可以仿照ruby来搞:
void scope_lock(T)(ref T t,void delegate() fn) { t.lock(); scope(exit) t.unlock(); fn(); } scope_lock(mutex, { do_something(); } ); 有scope就是好,比ruby,java之类用异常好多了。 汗一下,就是为了少打那几个字才用委托。 |
|
redsea
2007-10-11
那等 d2.0 AST macro 出来, 好像到时候是这样写:
macro guard(lock) { lock.lock() scope(exit) lock.unlock } 用的时候 { guard(mutex1) .... } 就完毕了. ahadf 写道 汗一下,就是为了少打那几个字才用委托。 |