我正在研究一个用C ++编写的项目,它使用自己创建的地图来存储数据 - 在这个意义上的地图更像是一个“地理”地图,所以是一个图像。有不同的线程读取和写入它。地图的数据存储在整数向量的std向量中。它的大小不会改变,只有通过getter和setter函数才能改变某些像素的内容。
我的问题如下: 有时一切都运行得很好,但更常见的是我会得到损坏的图像,因为像素的值会改变符号或者与它们应该完全不同。这可能是对像素的线程读/写访问的问题,如果是这样,我应该使用什么而不是标准向量? 我已经尝试使用互斥锁来确保只有一个线程读取或写入向量,但是这些读/写操作经常发生,如果我在每次操作时锁定向量,应用程序就会变得太慢。
答案 0 :(得分:6)
你需要某种锁定。为了防止这种情况太糟糕,你应该尽量减小锁的范围。例如,您可以锁定单个行向量,以便不同行上的写入不会相互干扰。哪种解决方案最适合您取决于您的访问模式和平台。
答案 1 :(得分:0)
进行多线程处理时,尽量尽量隔离线程的范围。
考虑和例子。想象一下,你有一面墙,你想要涂上黑白条纹。 为了加快工作,你决定雇用两名员工。
现在,您可以通过两种方式分配此作业。 1.将黑色条纹涂抹给一个工人,将白色涂抹给另一个工人。 2.将墙分成两个分区,并将左分区分配给一个工作人员,将右分区分配给第二个工作人员
现在哪一个可能会产生更好的表现?
在一般情况下,第二个更好,因为工人的工作区域是完全分离的,不需要等待另一个人完成他的工作。 当然第一种方法没有错,但是,有可能一个工人在某个地方画画而第二个人也可能到达同一个地方并且必须等待第一个工作完成。 现在想象如果你有10名工人每人只画一种特定颜色会发生什么。
多线程编程类似。如果您能够以更好的方式对问题数据进行分区,则可以使线程有效地工作。
答案 2 :(得分:0)
使用轻量级锁。那是在Windows上使用“CriticalSection”。或者编写自己的用户空间锁,例如喜欢在TinyThread(http://tinythreadpp.bitsnbites.eu/)。这些是用ASM编写的,实际锁定和解锁的开销几乎为零。
一旦你确定锁本身很快,如果事情仍然运行缓慢,那是因为你有锁争用。例如。多个线程都需要锁定相同的资源。在您的使用案例中,请考虑类似“读/写”互斥的内容。这是一个具有读取互斥锁和写入互斥锁的类。互斥锁上的“readLock”方法仅锁定几个周期以增加互斥锁上的引用计数。 “readUnlock”会减少引用计数。 “writeLock”锁定读取的互斥锁,并设置一个标志,使读者不会锁定读取的互斥锁。然后锁定写入互斥锁并执行写入操作。因此,您保证一次只能执行一次写操作,并且在写操作期间不会发生任何读操作。但允许同时读取。