我是否可以安全地将常量值写入C++中多个线程的变量
Can I safely write a constant value to a variable from multiple threads in C++?
特别是,我想设置一个函数指针的值。为简单起见,我想从多个线程多次执行此操作,但始终以这样的简单方式:
typedef void (*F)();
F f = 0;
void foo()
{
}
// called many times from multiple threads
void set()
{
f = &foo;
}
int main()
{
set(); // also other threads can invoke it at any time
f();
return 0;
}
因此,最初函数指针为 NULL,然后在首次执行代码时变为 &foo。我想知道是否由于任何非原子写入操作,函数指针可能会中断。
保证设置后首次读取。
编辑:我澄清:
- 我使用函数指针的主要原因是删除模块之间的一些依赖关系。这是一个大型真实项目的一个小元素。我真的不能直接叫'foo'。 我
- 知道如何编程,我不需要有关互斥锁之类的基本信息。我的问题是,如果没有互斥锁,这是否安全。
- 在代码中保证没有其他线程将指针设置为&foo以外的任何内容。
您是否考虑过使用 std::mutex
和 std::lock_guard
来强制实施线程安全?
例如
{
std::lock_guard<std::mutex> lg(my_mutex);
f = &foo;
// then use f to perform your operation
}
在闭合大括号之后,lock_guard
落出范围并解锁您的mutex
。这意味着设置f
的人可以安全地使用该函数指针,因为知道另一个线程在设置函数指针和尝试使用它之间没有更改函数指针。
该标准说你的代码调用未定义的行为。但是在你的特定情况下,即使用你的特定编译器和架构,你的代码实际上可能是没有问题的。因此,从理论的角度来看,您的代码是不行的。从实际的角度来看,答案取决于您的具体情况,绝不是一般性的。就个人而言,我建议用std::atomic<F> f(0);
替换F f = 0;
,以便保证代码在所有情况下都没问题。
只是为了说明代码中断的情况:实现可能会选择在每次写入操作之前清除目标。这样的实施是合法的,符合标准,尽管不一定是获奖:)
我认为这更像是一个线程同步问题,而不是与 c++ 相关的问题。您的问题的答案是,是的,您可以在 c++ 中安全地将值写入变量/指针(不确定常量是什么意思;在我看来,您只是想分配一个函数指针),您只需要使用互斥,以便线程在您不希望它们覆盖时不会覆盖该值
根据您最终想要实现的目标,您可能需要多个互斥锁(即,如果您想确保线程分配函数指针的特定顺序),但这绝对是安全执行此操作的方法。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 用C++中的一个变量定义一个常量
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 你能重载对象变量名本身返回的内容吗
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 尝试通过多个向量访问变量时,向量下标超出范围
- 试图让变量检查数组中的某些内容
- Cpp-Tuple使用带有变量的get
- 将包含C样式数组的对象初始化为成员变量(C++)
- 当vector是tje全局变量时,c++中vector的内存管理
- 通过多个头文件使用常量变量
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 执行函数时导致崩溃的变量
- 变量没有改变?通过向量的函数调用