除非您的 C 类成员函数的实现使用自修改代码(不太可能),否则访问程序内存本身不会成为问题。您的问题将是访问共享的可变数据和资源。
如果我正确理解了这个问题,您是说您将创建一个类“C”的新实例,并从另一个线程专门调用 C 类的成员函数。
例如伪代码:
void thread1() {
auto_ptr<C> pc(new C());
while (1) {
pc->f();
}
}
void thread2() {
auto_ptr<C> pc(new C());
while (1) {
pc->f();
}
}
由于函数 C::f() 中的代码不会更改,因此并发执行它是安全的。
但是,如果 C::f() 中的代码访问任何共享数据,那么除非您进行线程同步,否则它是不安全的。
例如,如果 C::f() 看起来像这样并且 C 有一个成员变量 ' int i_
' 那么这是安全的,前提是没有其他线程更改该值:
void C::f() {
++i_;
}
仅当没有其他线程读取或修改 C 的“i_”成员的该实例时,这才是安全的。在某些情况下,如果只有其他线程读取可能i_
是安全的,但前提是您可以保证写入i_
是原子的。还有更多关于指令顺序的警告以及您在程序中其他地方可能期望的内容,因此任何对此类内容的依赖都需要格外小心。在这个人为的例子中,没有其他线程会知道'C'的实例,所以它会很好。
如果 C::f() 看起来像这样:
void C::f() {
static int i = 0;
std::cout << i++ << std::endl;
}
那么它肯定是不安全的。静态 int 是共享数据 - 所有对 C::f 的调用都可以访问相同的数据,无论它是什么实例。' ' 的静态初始化程序存在数据竞争i
(第一次将其设置为零,编译器将为其插入一些簿记数据)。此外, ' ' 的增量i
可能不是原子操作——因此它是不安全的。
这里使用全局变量std::cout
也不是线程安全的。即使输出流在内部实现了互斥锁,您也在这里执行了两个单独的操作,并且您可能会遇到竞争。如果输出流内部没有线程同步,那么您可能会有各种未定义的行为。