我有一个相当简单的问题,但答案似乎无法回避我。如果我有多个相同c ++类的对象,每个对象都在自己的线程中,我是否需要了解并发访问问题?或者对于单独的实例,事物是自动线程安全的吗?当然我会期待静态方法的问题,但是实例方法呢?
答案 0 :(得分:2)
如果每个帖子中都有单独的对象,那么你就可以了。如果您在该类中有静态成员变量,则可能会遇到问题。
显然,如果您的线程函数正在访问全局或共享数据,这仅适用于所讨论的类对象的数据,那么通常的多线程问题将适用。
答案 1 :(得分:2)
这取决于。通常,类的一个实例将独立于其他实例上的操作。如果在单个线程中就是这种情况,那么多线程也是如此。
例如,考虑表示Point的值类型类。
class Point {
public:
int x, y, z
};
一个线程中此类的实例不受另一个线程中不同实例上的操作的影响。
但是,类的实例可以与其他对象进行交互。如果两个实例可以与同一个对象进行交互,那么是的,您确实需要关注线程安全性。
答案 2 :(得分:1)
实例变量都是独立的。因此,如果实例方法仅使用实例和局部变量,则无需担心线程安全。
答案 3 :(得分:0)
只要来自一个对象的线程不调用另一个对象上的方法,就应该没有问题。
但如果您有递归方法并且正在获取方法中的互斥锁,那么您可能会遇到死锁。如果是这种情况,您将需要使用递归互斥锁。
答案 4 :(得分:0)
问题的根源在于如何在内存中布置对象。假设不涉及静态数据成员(很少见),每个对象独立于相同类型的其他对象,因为这样的对象(如内存中所示)仅由对象的多个数据成员组成。例如,假设类型定义
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
本身只包含内存中的一对双打(在这种情况下,堆栈上有一对连续的双打);而your_loc
本身只包含一对双打。所以,你看,就数据而言,Location
只不过是两个双精度的结构。
但是,你问:构造函数和antipode()
等等是什么?答案是它们每个只存在一次 - 而且,就内存而言,它们并不直接与数据相关联。单独的编译器将数据与函数相关联。线程不关心。
如果你根据上述情况考虑到这一点,那么就会怀疑你所得到的答案将会落在你身上。
答案 5 :(得分:0)
您可以粗略地将C ++项目分为4类:
thread_local
存储限定符;见下一点总而言之,您不必担心方法或功能,也可以自由地共享常量。
在中间范围内,请确保不要共享(甚至是无意中)本地变量,至少在没有确保正确同步访问的情况下是这样。
最后,要非常警惕全局。