静态函数和多线程中的 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.
}
如何创建一个静态函数,其变量不需要在其中创建(用于计算问题),同时考虑到该函数可以被不同的线程调用? 示例:
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.
}