静态函数和多线程中的 C++ 静态成员

C++ static members in static functions and multithreading

如何创建一个静态函数,其变量不需要在其中创建(用于计算问题),同时考虑到该函数可以被不同的线程调用? 示例:

class calcul {
    static double **v1, **v2, ...,**vn;

public:
    calcul();
    ~calcul();

    static void matrix();
}; 

这样 matrix() 使用 v1, ..., vn.

问题是:当从不同线程多次调用 calcul::matrix() 时,这是否会产生冲突,即与线程 A 相关的 v1 可以由线程 B 修改?

我的 objective 使用 'static' 是符合人体工程学的,因为我不会每次都需要创建相应的对象。事实上 Class 'clacul' 将是需要用于实时应用程序的库的一部分。这意味着可以每毫秒调用一次 calcul()。

创建静态变量的方法是,按照自己的方式声明,然后再定义;

double calcul::v1, calcul::v2;   // same for other variables

这种类型的静态变量定义必须恰好出现在项目中的一个翻译单元(也称为成为对象的源文件)中。

如果您希望从多个线程调用 calcul::matrix(),那么每个线程都需要同步访问静态变量(例如,使用互斥锁)。否则,您会遇到竞争条件、部分完成时操作被抢占等问题。这可能意味着变量获得意外值。

您可以将值设置为非 static,因为它们仅在函数中局部使用:

void matrix() {
    double v1, ..., vn;
    // ..
}

或者您可以在矩阵中引入某种同步原语以防止多个线程同时访问它:

class calcul {
    std::mutex mtx;
    static double v1, ..., vn;
};

void matrix() {
    std::lock_guard<std::mutex> lk(mtx);
    // ...
};

最后,如果你的编译器支持,你可以使变量 static thread_local:

class calcul {
    static thread_local double v1, ..., vn;
};

哪个呢,来自 [basic.stc.thread]:

1 All variables declared with the thread_local keyword have thread storage duration. The storage for these entities shall last for the duration of the thread in which they are created. There is a distinct object or reference per thread, and use of the declared name refers to the entity associated with the current thread.

2 A variable with thread storage duration shall be initialized before its first odr-use (3.2) and, if constructed, shall be destroyed on thread exit.

静态变量来自您的 class calcul 命名空间,并且只在内存中分配一次,因此对于您拥有的每个对象或线程都是相同的。

每当您尝试从不同的线程访问相同的变量(相同的内存地址)时,您需要使用 Mutex 或 Semaphores,以便安全地执行 transactions/operations。

示例:

#include <mutex>

class calcul{
    std::mutex mtx;
    ....
}

void matrix()
{
   //lock the resources below to the current thread only
   mtx.lock();

   //do stuff with the variables (common resource)

   mtx.unlock(); //when the current thread is finished, unlock the resource.
}