【发布时间】:2022-07-31 18:20:36
【问题描述】:
虽然我遇到了一些问题,但我开始在我的应用程序中引入互斥锁以实现多线程兼容性。
我有 1 个线程用于构建用户数据,另一个用于渲染数据的线程让我们调用这个线程 2。
我在线程 1 中创建数据,然后 .lock,将数据推送到数组中,在线程 1 中使用 .unlock(),然后在线程 2 中读取此数据。当前在线程 2 中 I .lock();,循环数组显示用户数据,然后 .unlock();但这会导致我出现性能问题,因为线程 2 比线程 1 快,因此会导致渲染出现一些延迟。从线程 2 中删除 .lock 和 unlock 使我的滞后问题消失,我想知道这是否会导致任何问题?
【问题讨论】:
-
你在使用 std::mutex 吗?如果是这样,用 std::scoped_lock<:mutex> 或 std::unique_lock<:mutex> 锁定。像这样:
std::scoped_lock<std::mutex> lock{mtx};。锁需要尽可能短,你会遇到“没有免费的午餐”的问题。线程同步需要时间,您需要在设计中考虑到这一点。 -
我正在使用 std::mutex PlayerData;确切地说,然后我填充了一个巨大的数组,不幸的是,这需要时间,因为有很多数据需要填充
-
如果你从线程 2 中移除锁和解锁,那么你将没有线程同步,你可能会在线程 2 中渲染损坏的数据,因为不能保证数据在一个阅读时的一致状态。
-
不锁定两个线程可能会导致一个线程看不到一致的数据状态。如果两个线程都必须持有锁来完成大部分工作,那么您最终只会得到多线程的缺点,而不是它的好处。您可以通过使用 2 个数据副本并锁定互斥锁仅用于交换线程副本来解决此问题,例如
std::vector<Data>data; ...expensive computations ... { std::lock_guard lock(mutex); renderThreadData.swap(data); /* <-- inexpensive operation */ }你甚至可以使用std::atomic来解锁... -
minimal reproducible example 将有助于说明您的问题
标签: c++ multithreading mutex