【发布时间】:2015-07-16 09:41:31
【问题描述】:
请你帮帮我。
假设我有 p - 1 个读线程和一个写线程。它们都在一个原子 int 变量中读取和写入。如果所有读取和写入同时发生,写入操作会等待 p - 1 次吗?我有疑问,因为当原子操作发生时,会有一些奇怪的锁(在汇编程序中),我担心它会锁定内存(变量所在的位置)。因此,写操作可能会等待 p-1 读取。会发生吗?
下面是一些简单的代码:
#include <atomic>
#include <iostream>
#include <thread>
#include <vector>
std::atomic<int> val;
void writer()
{
val.store(7);
}
void read()
{
int tmp = val.load();
while (tmp == 0)
{
std::cout << std::this_thread::get_id() << ": wait" << std::endl;
tmp = val.load();
}
std::cout << std::this_thread::get_id() << " Operation: " << tmp * tmp << std::endl;
}
int main()
{
val.store(0);
std::vector<std::thread> v;
for (int i = 0; i < 1; ++i)
v.push_back(std::thread(read));
std::this_thread::sleep_for(std::chrono::milliseconds(77));
writer();
std::for_each(v.begin(), v.end(), std::mem_fn(&std::thread::join));
return 0;
}
谢谢!
【问题讨论】:
-
我不知道 atomic 的真正作用,但很有可能是:1. 锁定 2. 访问 3. 解锁。所以如果你想prioritize 访问,atomic 对它来说太简单了。您应该设置更复杂的锁定结构。应该有“写请求”标志 1.写入时,在修改值之前设置它,修改值,然后清除它。 2. 读取时,在设置此标志之前不要触摸变量。结果:当读取访问到达时,它将暂停直到写入完成。
-
但是同样的问题出现了。当我在写入时设置标志时,它可能会等待一些读取访问结束。而且我担心(写入线程的)等待时间与读取访问次数成正比。
-
我还有一个想法:双缓冲。有两个值,A和B。有一个index变量,指向实际值,可以是A或B。读线程是从实际值中读取,由描述索引。 Write 可以解决问题:它将值写入 1 - index,然后交换,index := 1 - index。因此,在写入之前不会有任何读取“排队”。您必须使用通用锁来读取 A 和 B 以避免交换时的顺序问题(避免:一些读取 A 在锁 A 处挂起,因此到达的读取 B 以新值更快完成,因为没有人挂在锁 B 上) .一把锁,读顺序就OK了。
标签: c++ multithreading