从一个对象线程中使用 const 方法是否安全
Is using a const method from one object thread safe?
我不确定这是否是重复的,我已经浏览了许多帖子,但它们似乎与我的问题不够接近。
我想从一个对象使用 const 方法来同时更改其他对象。该程序基本上需要我在重力的影响下移动一个粒子,我想对所有粒子并行运行它。 我做了一个物理课,在该课中,我有一个 const 方法来移动粒子对象。
这里有一些示例类可以更好地理解我。
/**
* Particle.h
*/
#ifndef __Particle__sim__
#define __Particle__sim__
class Particle {
private:
double height;
double velocity;
public:
const double getHeight() const;
const double getVelocity() const;
void setHeight(const double&);
void setVelocity(const double&);
};
#endif
/**
* Physics.h
*/
#ifndef __physics__sim__
#define __physics__sim__
#include <thread>
#include <vector>
#include "Particle.h"
class Physics {
private:
double gravity;
double timeStep;
void moveParticle(Particle&, const double) const;
public:
Physics(const double g, const double t);
void moveParticles(std::vector<Particle>&, const double) const;
};
#endif
/**
* Physics.cpp
*/
#include "Physics.h"
using namespace std;
Physics::Physics(const double g, const double t) : gravity(g), timeStep(t) {}
void Physics::moveParticle(Particle& particle, const double time) const {
// move particle under gravity
}
void Physics::moveParticles(vector<Particles>& particles, const double time) const {
vector<thread> threads;
threads.reserve(particles.size());
for (auto& p : particles) {
threads.push_back(thread(Physics::moveParticle&, this, std::ref(p), time));
}
for (auto& t : threads) {
t.join();
}
}
这基本上是我的主要
/**
* main.cpp
*/
#include <vector>
#include "Physics.h"
#include "Particle.h"
using namespace std;
int main() {
vector<Particle> particles;
// insert 100,000 particles
Physics physics = Physics(-9.81, 0.01);
physics.moveParticles(particles, 5.0);
return 0;
}
那么physics.moveParticle(Particle&, const double)
线程在这里安全吗?
简短与甜蜜:我想使用一个 Physics 对象中的一种方法来制作多个线程来移动我程序中的所有粒子,但我不确定我编写的 const 方法是否线程安全。我不明白为什么不,但我无法证明它。
乍一看,这应该是线程安全的。
我们需要看到Particle::setHeight的实现才能绝对确定。如果它做了类似写入全局数组的事情怎么办?这将是愚蠢的,但我们不能确定。
但是,您的粒子看起来非常简单。更线程安全的是根本不改变它。使它们不可变,并在每次计算时创建一个新计算。
您仍可以通过将新粒子分配回旧粒子来更改它们。
但是,如果您真的想进入线程,那么这里一个很好的技术是拥有两种世界状态:上一个和下一个。这些与每个更新步骤交换。每个更新步骤从上一个步骤读取并写入下一个步骤。这允许其他线程(如图形)显示从以前的读取,而无需不断锁定像粒子这样的小东西。
这样,一个不可变的粒子根本不会减慢任何东西的速度。事实上,编译器会将机器代码重写为nextParticles[i] = updateParticle(prevParticles[i])
直接赋值到其在内存中的最终位置。这就是RVO或NRVO。
它看起来是线程安全的。 特别是,如果每个生成的线程读取或写入的唯一(不可变)数据是线程自己的相应 Particle 对象,则就线程而言,没有共享数据。 (当然,Physics 对象本身是共享的,但由于您在子线程的生存期内没有修改 Physics 对象,因此 Physics 对象在操作期间实际上是不可变/只读的,并且生成的线程对 Physics 对象的任何只读访问都不会成为争用条件的来源)
- 从 const 对象访问非 const 方法
- 为什么我可以调用一个从const方法更改成员的方法
- 使用新的c++返回值语法的Const方法
- const_cast const 方法中的"this"将"this"分配给外部变量?
- const 方法使用引用修改对象
- 从具有相同基数的另一个派生类调用派生类的非 const 方法
- 返回非常量引用编译的 Const 方法
- C++:无法从 const 方法返回对象的shared_ptr
- 是否可以从 const 方法迭代链表
- 为什么在const和非const方法中删除代码重复不是不确定的行为
- 在使用指向 const 和非 const 方法的成员指针时减少模板专用化的数量
- "可变"变量只能由 const 方法之一可变?
- Golang中的const方法
- C++ 逻辑恒常性和 const方法的按值返回
- c++将标志添加到const方法中
- C++防止const方法通过成员指针或引用更改数据
- 为什么 const 方法不覆盖 C++ 中的非 const 方法?
- 如何在const方法中迭代映射
- 为什么没有标准化的方法来避免const方法的代码重复
- 修改 const 方法中的 pointee 值