关于“纯”函数对象的const和线程安全性

时间:2018-01-17 08:03:49

标签: c++ c++11 thread-safety const

在我的程序中,有“函数”采用适当的参数,执行一些计算,并返回相应的结果。这些“功能”具有一些外部可见的内部状态;它们主要是临时结果的内存缓冲区。这意味着,那些“功能”没有任何逻辑状态。

这些内存缓冲区和其他内容实际上正在从每次调用调用到调用,因为所需的缓冲区大小可能会根据输入数据而改变。

虽然这些缓冲区仅适用于临时工,但我需要控制它们的生命周期,构建/破坏线程等。我不希望从调用站点提供这些临时值,因为它们的使用只是“函数内部” ”。所以我认为那些“函数”需要以类的形式实现(而不是使用/不使用静态变量)。

由于没有外部可见的状态变化(尽管有一些状态已经给出并且在构造之后永远不会改变),我认为最好用{{来限定函数(我的意思是函数调用运算符或其他)来{{ 1}}。但后来我不确定如何处理这些临时资源的线程安全性,因为众所周知,在C ++ 11中,const默认表示线程安全。

目前功能的使用主要是单线程的;只有极少数情况下,这些函数的实例由多个线程共享,所以我在必要时外部锁定了这些调用。 (更准确地说,有一个锁保护整个系列的计算。当另一个线程想要执行计算时,它获得该锁。当前没有与每个函数关联的锁。)

函数的实现与外部分离,因为我计划在其他项目中使用它们。

使用函数实现中的锁来保护计算是否更好?或者只是将函数保留为非常量,尽管它们只是(至少在概念上)纯函数?或者只是将它们标记为const,尽管它们不是线程安全的(因此不是真正的“常量”)?或者我应该考虑一种不同的方法吗?

1 个答案:

答案 0 :(得分:2)

最简单的解决方案是使用thread_local缓冲区。

int T::myfunction(int arg) const
{
    static thread_local U mybuffer;
    // impl...
}

thread_local将为您提供线程安全性,因为每个线程都将使用自己的缓冲区。由于函数内部为static,因此在每次函数调用后都会保留缓冲区。