线程安全和静态函数

Posted

技术标签:

【中文标题】线程安全和静态函数【英文标题】:Thread Safety and static functions 【发布时间】:2012-12-28 05:16:22 【问题描述】:

假设我有一个:

class base

    base()f(this);;

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

    int d;
;

现在,如果我在 2 个单独的线程上创建一个 base 类型的对象,方法 f 会被认为是线程安全的吗? 我问这个问题是因为通常据我所知,对于线程安全的方法,它不应该使用静态成员或全局变量。但是从上面的例子可以看出,我决定不将变量d设为静态,而是通过base的运行实例调用它。

另外,我认为我不需要用互斥锁保护这一行:(b->d)++;,因为每个线程都有一个单独的 base 实例和变量 d。

我的分析正确吗?有什么需要注意的吗?

【问题讨论】:

你是对的,只要基指针是线程特定的,你就很好。 你能编译你的程序吗?它应该抛出一个编译错误 @stamhaney,不,我没有,我只是想弄清楚这个理论:) 请指出问题 构造函数应该是公共访问权限 不必在公共访问权限下(单例通常使用私有/受保护的构造函数),但对于大多数用例来说,这是肯定的。不过,我认为很明显这只是一个示例,大脑的编译器比 CPU 的要轻松得多。 【参考方案1】:

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

以下是修复未定义行为的方法:

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

现在d 已在初始化列表中初始化,您的程序以可预测的方式运行。

【讨论】:

谢谢 :) 这是完美的

以上是关于线程安全和静态函数的主要内容,如果未能解决你的问题,请参考以下文章

可重入和线程安全

使用线程不安全的静态变量锁定嵌套函数

线程安全与可重入

静态函数范围对象的构造是线程安全的吗?

可重入和线程安全简单介绍

静态初始化不安全调用的线程安全