线程安全和静态函数

6

假设我有一个:

class base
{
    base(){f(this);};

    static void f(base * b) {(b->d)++;};

    int d;
};

现在,如果我在两个不同的线程上创建一个类型为base的对象,方法f是否被认为是线程安全的? 我问这个问题是因为通常我所知道的是,为了使方法线程安全,它不应该使用静态成员或全局变量。但是从上面的示例中可以看出,我决定不将变量d设置为静态变量,而是通过运行实例的base来调用它。 此外,我认为我不需要用互斥锁保护这一行:(b->d)++;,因为每个线程都会有一个独立的base实例和变量d。 我的分析正确吗?还有什么需要注意的吗?

1
你是对的,只要基本指针是线程特定的,就没问题了。 - perreal
你能编译你的程序吗?它应该会抛出一个编译错误。 - stamhaney
@stamhaney,我还没有,我只是在尝试理解理论 :) 请指出问题。 - Kam
构造函数应该在公共访问下。 - stamhaney
不一定需要公共访问(单例通常使用私有/受保护的构造函数创建),但对于大多数用例来说,可以这样做。我认为很明显这只是一个例子,而大脑的编译器比CPU的更加放松。 - Soup d'Campbells
1个回答

8

是的,您的构造函数是线程安全的,因为它只访问实例变量(具体来说,是d)。它确实表现出未定义的行为,因为它从未初始化的d中读取以执行增量,但这与线程安全无关。

以下是如何修复未定义行为:

base(): d(0) {f(this);};

现在,在初始化器列表中初始化了d,您的程序会按照可预测的方式运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接