【发布时间】:2020-12-15 11:35:04
【问题描述】:
我是 C++ 多线程的新手(显然它与 python 多线程/多处理不同,因为多个线程可以在单个进程中使用多个 CPU)。我知道如果 2 个线程尝试同时更改相同的数据,或者如果一个线程读取某些内容而另一个线程正在更改它,则会发生竞争条件,但我不确定以下情况是否需要同步:
假设我有以下课程:
class Animal{
public:
string name_;
Animal(string name);
~Animal();
};
class Dog : public Animal{
public:
int price_;
Dog(string name, int price);
~Dog();
};
class Cat : public Animal{
public:
int price_;
Cat(string name, int price);
~Cat();
};
void do_stuff(){
Animal* a = new Dog("Foo", 3);
}
是否安全:
- 让一个线程执行 static_cast 或 dynamic_cast 而另一个线程正在读取或写入对象?
// thread 1
a->name = "Bar";
// thread 2
Dog* d = static_cast<Dog*>(a);
- 有一个线程读取对象的属性,而另一个线程正在写入同一对象的另一个属性?根据这篇文章 (Accessing different data members belonging to the same object from 2 different thread in C++) 似乎没问题,但显然它会导致缓存问题?
谢谢
【问题讨论】:
-
(1) static_cast 甚至根本不访问对象 - 只是指针。 (2) 你看答案了吗?
-
谢谢!是的,我阅读了答案,发现它会使事情变慢,但我不完全理解数据成员对齐的含义
-
对齐 - CPU 和内存没有类型的概念。整数是一种语言结构。编译器为 int 保留 4 个字节。如果这 4 个字节跨越一个高速缓存行,则可能需要 2 个 CPU 指令来完成它(即它不是原子的)。但是,编译器通常在 4 字节/8 字节边界上对齐类型。主流 CPU 加载和存储操作在字大小的字对齐位置上是原子的。位域是指不同的变量具有奇怪的大小并共享相同的字节。 (例如:A 是 17 位,B 是 15 位。两者都存储在一个 4 字节块中)。
-
虚假共享 - 今天的缓存行是 64 字节。写入高速缓存行的不同字是原子的,但会导致多个 CPU 之间的高速缓存争用。根据定义,这不是数据竞争,而是由于缓存利用率而导致性能不佳。
标签: c++ multithreading inheritance caching casting