C++ 同一对象的多个副本(C+;+;):线程安全?
我有一个相当简单的问题,但我似乎找不到答案。如果我有多个C++类的对象,它自己的线程中的每个对象,我需要知道并发访问问题吗?或者,对于单独的实例,事情是自动线程安全的吗?当然,我认为静态方法会有问题,但是实例方法呢 实例变量都是独立的。因此,如果您的实例方法只使用实例和局部变量,则不必担心线程安全。只要一个对象的线程不调用另一个对象上的方法,就应该没有问题C++ 同一对象的多个副本(C+;+;):线程安全?,c++,multithreading,C++,Multithreading,我有一个相当简单的问题,但我似乎找不到答案。如果我有多个C++类的对象,它自己的线程中的每个对象,我需要知道并发访问问题吗?或者,对于单独的实例,事情是自动线程安全的吗?当然,我认为静态方法会有问题,但是实例方法呢 实例变量都是独立的。因此,如果您的实例方法只使用实例和局部变量,则不必担心线程安全。只要一个对象的线程不调用另一个对象上的方法,就应该没有问题 但是,如果您使用递归方法并且正在获取该方法中的互斥量,那么仍然可能会遇到死锁。如果是这种情况,您将需要使用递归互斥锁。如果每个线程中都有单独
但是,如果您使用递归方法并且正在获取该方法中的互斥量,那么仍然可能会遇到死锁。如果是这种情况,您将需要使用递归互斥锁。如果每个线程中都有单独的对象,那么就可以了。但是,如果该类中有静态成员变量,则可能会出现问题
显然,这只适用于相关类对象的数据,如果线程函数正在访问全局或共享数据,则通常的多线程问题将适用。这取决于具体情况。一个类的一个实例通常独立于其他实例上的操作。如果在单个线程中是这种情况,那么在多个线程中也是如此
例如,考虑一个表示一个点的值类型类。
class Point {
public:
int x, y, z
};
一个线程中此类的实例将不受另一个线程中不同实例上的操作的影响
但是,类的实例可以与其他对象交互。如果两个实例可以与同一个对象交互,那么是的,您确实需要关注线程安全。问题的根本在于对象在内存中的布局。假设不涉及静态数据成员(很少),则每个对象都独立于相同类型的其他对象,因为内存中的对象本身仅由对象的几个数据成员组成。例如,假设类型定义
class Location {
private:
double latitude1;
double longitude1;
public:
double latitude () const { return latitude1; }
double longitude() const { return longitude1; }
Location(const double lat0, const double long0) {
latitude1 = lat0;
longitude1 = lon0;
}
// Calculate the Location at exactly the furthest
// point on earth (implemented elsewhere).
Location antipode();
};
假设该类型的单独对象在其他地方实例化为
Location my_loc(-100.0, 35.0);
const Location your_loc(15.0, 45.5);
然后,my_loc
本身只包含内存中的一对双精度(在本例中,堆栈上的一对连续双精度);而您的_loc
本身只包含一对单独的双打。所以,你看,就数据而言,位置
不过是两个双精度的结构
但是,您会问:构造函数和antipode()
,等等呢?答案是它们对于类只存在一次——并且,就内存而言,它们与数据没有直接关联。只有编译器将数据与函数相关联。线程不关心这个
如果你根据前面的观点来思考这个问题,那么你会怀疑你所得到的答案会落在你身上。 < P>你可以大致分类C++的4个类别:
- 只读:文本、常量、函数等。。。在代码执行过程中无法修改,因此共享它们本质上是安全的
- 全局变量:命名空间范围内的全局变量、类的静态属性、函数中的局部静态变量等。。。可以修改,因此必须使用适当的多线程感知机制
- 线程局部变量:上述所有变量,但标记为
存储限定符;见下一点thread\u local
- 实例变量:类或结构属性、函数、局部变量。。。只要未明确共享,就可以安全使用
最后,要特别提防全球化者。@Mathematician 1975:顾名思义,全球化者并非独立的。谢谢大家,这是一个详尽的答案。我也学到了一些新东西:)谢谢大家,这是一个详尽的答案。我也学到了一些新东西:)