【发布时间】:2020-06-09 22:21:46
【问题描述】:
考虑下面的代码sn-p
int index = 0;
av::utils::Lock lock(av::utils::Lock::EStrategy::eMutex); // Uses a mutex or a spin lock based on specified strategy.
void fun()
{
for (int i = 0; i < 100; ++i)
{
lock.aquire();
++index;
std::cout << "thread " << std::this_thread::get_id() << " index = " << index << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
lock.release();
}
}
int main()
{
std::thread t1(fun);
std::thread t2(fun);
t1.join();
t2.join();
}
我使用用于同步的互斥锁得到的输出是第一个线程 1 完全执行,然后是线程 2。 在使用自旋锁(使用 std::atomic_flag 实现)时,我得到了交错的线程之间的执行顺序(线程 1 的一次迭代,然后是线程 2 的另一次迭代)。后一种情况的发生与我在执行迭代时添加的延迟无关。
我了解互斥锁只保证互斥而不保证执行顺序。我的问题是,如果我想要一个执行顺序,使得两个线程以交错方式执行,是否使用自旋锁是推荐的策略?
【问题讨论】:
-
如果你想强制交错执行,你需要让每个线程等待轮到它,而不是竞争自旋锁。
-
您可以拥有两个轮流使用的互斥锁。或者你可以有一个条件变量来保护另一个变量,说明轮到谁了。
-
我看不出这样做的目的。为什么?
-
请考虑不要问是/否问题。答案显然是“不”,因为 C++ 规范中没有任何内容需要这种行为,而且您不能对底层硬件和操作系统现在和永远运行的方式做出任何假设。
-
我不太明白运行线程互斥的动机。当我引入线程时,我想同时运行它们——尽可能少地同步,也就是通信。当然,通常不同步就无法完全完成。例如对于生产者-消费者或共享资源。但是,要按意图交错运行线程......在这种情况下,我会考虑如果没有线程的所有额外麻烦,这是否不能做得更好。 (对不起,只是我的两分钱......)
标签: c++ multithreading mutex spinlock