我听说过这些与并发编程有关的词,但它们之间的区别是什么?
信号量和自旋锁之间的基本区别是什么?
什么时候我们会使用信号量而不是自旋锁?
主要的原因使用原子能超过互斥,是互斥是昂贵的,但与默认的内存模型atomics是memory_order_seq_cst,这不仅是因为贵吗?
问题:并发使用锁的程序可以和并发无锁程序一样快吗?
如果是这样,除非我想memory_order_acq_rel用于原子,否则它可能不值得.
编辑:我可能会遗漏一些东西,但基于锁定不能比无锁更快,因为每个锁也必须是一个完整的内存屏障.但是,通过无锁,可以使用比内存障碍更少限制的技术.
那么回到我的问题,没有锁定比基于新的C++ 11标准的默认锁定更快memory_model?
"无锁定> =在性能测量时基于锁定"是真的吗?我们假设有2个硬件线程.
编辑2:我的问题不是关于进度保证,也许我正在使用"无锁"脱离上下文.
基本上当你有2个共享内存线程时,你需要的唯一保证就是如果一个线程正在编写然后另一个线程无法读写,我的假设是简单的原子compare_and_swap操作比锁定互斥锁要快得多.
因为如果一个线程甚至从未触及共享内存,您将无缘无故地反复锁定和解锁,但使用原子操作时,每次只使用1个CPU周期.
关于注释,当争用很少时,自旋锁与互斥锁是非常不同的.
我正在用IPC进行实验,特别是使用Mutex,Semaphore和Spin Lock.我学到的是Mutex用于异步锁定(具有睡眠(根据我在NET上读到的理论))机制,信号量是同步锁定(具有信号和睡眠)机制,并且自旋锁是同步但非睡眠机制.
任何人都可以帮我澄清这些东西吗?另一个疑问是关于Mutex,当我用线程和互斥体编写程序时,一个线程正在运行另一个线程不处于Sleep状态但它不断尝试获取Lock.所以Mutex正在睡觉或不睡觉???
我有一段遗留代码的包装器。
class A{
L* impl_; // the legacy object has to be in the heap, could be also unique_ptr
A(A const&) = delete;
L* duplicate(){L* ret; legacy_duplicate(impl_, &L); return ret;}
... // proper resource management here
};
Run Code Online (Sandbox Code Playgroud)
在这个遗留代码中,“复制”对象的函数不是线程安全的(当调用相同的第一个参数时),因此它没有const在包装器中标记。我想遵循现代规则:https : //herbsutter.com/2013/01/01/video-you-dont-know-const-and-mutable/
这duplicate看起来是实现复制构造函数的好方法,除了它不是的细节const。因此我不能直接这样做:
class A{
L* impl_; // the legacy object has to be in the heap
A(A const& other) : L{other.duplicate()}{} // error calling a non-const function
L* duplicate(){L* ret; legacy_duplicate(impl_, &ret); return ret;} …Run Code Online (Sandbox Code Playgroud) c#lock关键字是否使用"让步","自旋锁定"或混合方法来处理争用?
到目前为止,我对.net锁定语句的搜索没有找到答案.如果我找到了,我会发布.到目前为止,我所能找到的是什么时候应该使用一个自旋锁...用Mecki接受的措辞很好.
但我正在寻找关于.net/c#的一些明确的答案或文件,如果有人的话.
我在C#中尝试使用线程,结果创建了以下类.我试图避免任何竞争条件,但使用时会出现死锁.
该类使用两个不同的锁,一个用于简单操作的自旋锁,另外还有一个Monitor锁以在没有对象准备好的情况下等待.我最初使用EventWaitHandle,但发现种族条件由于WaitOne/ Set优先而不可避免.
注意,Monitor.Pulse不能先于Monitor.Wait,否则还有什么可能导致死锁?在5个线程使用TestPool容量为4 的类的情况下,死锁总是SpinLock在不规则的时刻发生.
internal class TestPool<T> where T : class
{
private int capacity;
private int unitPos;
private int waitUnitPos;
private int waitCount;
private int lockState;
private object lockObj;
private T[] units;
private Func<T> unitFactory;
public TestPool(int capacity, Func<T> unitFactory)
{
this.lockObj = new object();
this.unitFactory = unitFactory;
Init(capacity);
}
public T Fetch()
{
T unit;
Lock();
unit = (unitPos != capacity) ? …Run Code Online (Sandbox Code Playgroud) 目前在我的代码中我有这样的部分
boost::mutex Mymutex
void methodA()
{
boost::mutex::scoped_lock lock(Mymutex);
......
......
......
}
Run Code Online (Sandbox Code Playgroud)
我读到关键部分比互斥锁更快?所以我正在做这样的事情,我想知道这是否更快.
boost::recursive_mutex m_guard;
void methodA()
{
// this section is not locked
{
boost::lock_guard<boost::recursive_mutex> lock(m_guard);
// this section is locked
}
//This section not locked
}
Run Code Online (Sandbox Code Playgroud)
第二种方法更快吗?我主要使用互斥锁的原因是为了防止竞争条件和锁定对方法的访问,以便一个线程一次访问它.还有什么比这更快的吗?我的另一个问题是声明
boost::lock_guard<boost::recursive_mutex> lock(m_guard);
Run Code Online (Sandbox Code Playgroud)
似乎每次调用methodA()都会在堆栈上创建锁.我正在考虑将lock声明为静态变量,因此每次调用此方法时都不会在堆栈上创建它.在这种情况下,如何将m_guard添加到它.例如
boost::recursive_mutex SomeClass::m_guard; //This is static
boost::lock_guard<boost::recursive_mutex> SomeClass::lock //Suppose this is static
void SomeClass::methodA()
{
{
//How do i make lock "lock" mguard
}
}
Run Code Online (Sandbox Code Playgroud) 我试图QMutex在我的应用程序(蒙特卡罗模拟)中替换std::mutex,并且令人惊讶的是,计算速度除以3.互斥锁定/解锁性能成本从可忽略不计到线程时间的约66%.
我深入研究了实现源代码.我最初认为两者都是Win32线程的包装器(有一个额外的pthread层std::thread),但实际上Qt没有使用任何内核函数用于互斥锁,并且有自己的基于原子变量的内部实现.这个似乎要快得多.
谢谢
我想知道Mutex对象忙等待还是上下文切换出来(即拥有互斥锁的线程是否会进入休眠状态并稍后被中断唤醒),还是依赖于架构(即机器拥有的核心数)?我希望它实际上是一个上下文切换出来的.先感谢您.