所以我上学期参加了OS课程,我们有一个并发/线程项目。这是一架机场模拟器降落飞机/让它们朝着风吹的方向起飞。我们不得不用Java来做。所以现在决赛结束了,我很无聊,我试图用C ++ 11来做。在Java中,我在main中使用了一个synchronized变量(0 - 360)并将其传递给我正在使用的3个线程。我的问题是:你能用C ++ 11做到吗?它是一个基本的读写器,一个线程写入/更新风,另一个2(起飞/着陆)读取。
我通过在我的“threads.cpp”实现文件中使用全局wind变量来实现它。但有没有办法将变量传递给我想要的多个线程,并且所有线程都跟上它?或者我真的更好地使用全局变量并且不传递任何东西?(为什么/为什么不呢?)我在看std::ref()
但是没有用。
答案 0 :(得分:5)
您可以使用std::mutex
和std::lock_guard
来同步对共享数据的访问权限。或者,如果共享数据符合整数,则可以使用std::atomic<int>
而无需锁定。
如果要避免全局变量,只需在启动时将共享状态的地址传递给线程函数即可。例如:
void thread_entry1(std::atomic<int>* val) {}
void thread_entry2(std::atomic<int>* val) {}
std::atomic<int> shared_value;
std::thread t1(thread_entry1, &shared_value);
std::thread t2(thread_entry2, &shared_value);
答案 1 :(得分:2)
使用std::mutex
和std::lock_guard
模仿Java同步变量的作用(仅在Java中,这是秘密发生的,如果你不知道,在C ++中你明确地这样做了。)
然而,拥有一个生产者(只有一个风向),否则只有消费者,只需写入例如std::atomic<int>
变量具有宽松的排序,并从每个消费者中读取该变量,再次放宽排序。除非你要求所有飞机的全局视图是一致的(但是你必须运行锁步模拟,这使得线程无意义),所以不需要同步,你只需要确保任何值都是任何时候飞机读取最终都是正确的,并且不会出现乱码的中间结果。换句话说,您需要原子更新
轻松的内存排序也足够了,因为如果您只读取一个值,则不需要任何先发生过的保证。
原子更新(或更确切地说,原子写入)至少是一个数量级,如果不是更多,则更快。具有宽松排序的原子读取和写入在许多(大多数)主流架构上确实是普通的正常读取和写入。
变量不需要是全局变量,您也可以将它保存在主线程的模拟循环范围内,并将引用(或指针)传递给线程。
答案 2 :(得分:1)
您可能希望通过new
在std::shared_ptr
的堆上创建say,wind对象。将此指针传递给所有感兴趣的线程,并使用std::mutex
和std::lock_guard
进行更改。