保护多线程访问的类实例

时间:2011-01-30 07:13:41

标签: c++ c multithreading concurrency

我有一个包含许多实例的C ++类,我想让我的应用程序线程安全。 该类有一个成员和一个处理它的函数,例如:

class MyCls {
  int x;
  void f() { x++; }
};

我需要保护这个成员,所以据我所知,我有两个选择:

  1. 添加全局关键部分和 在触摸此会员之前输入。
  2. 在课程中添加一个关键部分 所以每个实例都会保护自己的成员。
  3. 这两种解决方案都是一个巨大的过度杀伤力:

    1. 两个不同的实例根本不应同步。
    2. 操作系统应该处理数百万个关键部分,实际上碰撞很少。
    3. 我可以使用其他解决方案或多线程设计模式吗?

4 个答案:

答案 0 :(得分:2)

不确定,但我认为可以使用Software transactional memory机制解决问题。有一堆implementations for C++

答案 1 :(得分:1)

至于您的第一个问题,每个实例都应该有一个成员互斥,为每个实例提供一个单独的关键部分。

至于第二个,我确信大多数pthread实现都使用futex实现它们的互斥锁。这意味着当没有争用时它们非常快,并且只有在存在争用时才需要操作系统干预。

答案 2 :(得分:0)

如果您不想使用锁或关键部分,那么最简单的解决方案就是不要将状态保留在对象本身中。如果你改变你的类,如下所示,它将是线程安全的:

// Class has no state, only operations on data. So it
// is thread-safe by nature.
class MyCls 
{
    int foo(int x = 0)
    {
        return ++x;
    }
};

// Usage
MyCls obj;
int x = obj.foo(); // x = 1
x = obj.foo(x); // x = 2

答案 3 :(得分:0)

如果你真的只需要增加那个成员(或类似的简单算术),你只需要原子操作。

  • 大多数(全部?)现代CPU都支持它们 本地指示。
  • 我不知道其他编译器, 但那些来自gcc家族的人有 他们是内置的。

不幸的是,这些似乎没有标准化的接口,但即将推出的C标准(C1x)将拥有它们。