如果我从另一个线程调用对象成员函数会发生什么?

时间:2012-03-14 07:56:39

标签: c++ multithreading

如果我在主线程中创建了一个C ++对象,然后启动另一个线程,并从该线程调用我创建的对象的公共成员函数,会发生什么?

如果公共函数有参数或操作私有对象成员,它是不同的吗?

它在windows,linux或mac os上的表现是否有所不同?

如果在堆栈上创建对象会发生什么?

6 个答案:

答案 0 :(得分:9)

有两点很重要:

  • 首先,您需要确保实例的生命周期超过其使用期限。
  • 第二,需要同步跨多个线程访问变量以防止竞争条件。

那是所有人。

答案 1 :(得分:4)

  1. 每个线程都有自己的堆栈,因此您可以拥有并发的执行流。使对象成为线程安全的是你自己的责任。

  2. 没关系。但是,私人成员是竞争条件的候选人。

  3. 如果在堆栈上创建对象,则无法从其他线程访问该对象。

答案 2 :(得分:3)

  

如果我在主线程中创建了一个C ++对象,然后启动另一个线程,并从该线程调用我创建的对象的公共成员函数,会发生什么?

取决于对象的生命周期。

如果在堆上创建对象(动态内存使用new),则另一个线程将正确访问对象的成员(假设没有竞争条件),除非通过调用{{1}结束对象的生命周期在第一个线程中。

如果在第一个线程中在堆栈(本地)上创建对象,那么如果在第二个线程中访问之前创建的对象的生命周期结束,则将具有* 未定义行为 *。

  

为什么你可以在第二个帖子中访问堆栈上的对象?

每个线程都有自己的堆栈,除非在线程堆栈上创建的对象有效且存活您将尝试访问不指向第二个线程中任何有效对象的地址位置。
请注意,每个进程都有一个地址空间,同一进程中的所有线程共享相同的地址空间,因此可以在第二个线程中访问该变量的地址。但是,您需要确保该地址包含有效对象。

  

如果公共函数有参数或操作私有对象成员,它是不同的吗?

访问说明符和多线程根本没有关系。
相同的访问说明符规则适用于所有线程。

  

在Windows,Linux或Mac OS上的行为是否有所不同?

所有操作系统都保证delete的答案。

答案 3 :(得分:2)

与原始行为相比,如果在堆上创建,则应该没有差异。然而,当然有一些罪魁祸首,通常称为“线程安全”。如果您从不同的线程访问同一个成员,则必须确保访问相同的资源不会导致“竞争条件”。

为避免竞争条件,您可以使用不同类型的“锁”,例如互斥锁等。当使用锁定对象时,还有另一个罪魁祸首:如果两个访问者彼此等待并且原始锁定,则会出现“死锁”的危险永远不会被释放。

答案 4 :(得分:2)

它会很好地运作。对象不属于任何特定线程,可以从任何地方调用。

但是,这很重要,同时在两个线程上调用成员函数会导致在一个线程中更新某些数据而在另一个线程中读取数据时出现问题。您需要安排代码以确保不会发生这种情况,或者确保线程协调访问(最有可能使用互斥锁)

答案 5 :(得分:2)

如果您从同一个地方调用它,会发生什么 线。执行相同的机器代码。唯一的潜力 区别在于你可以有多个线程访问对象 同一时间;这取决于你防止这种情况(至少如果有的话) 线程正在修改对象 - 否则,没有保护 需要)。

如果堆栈中有对象,则必须考虑生命周期 问题,但无论如何都是这样的;保存指向对象的指针 堆栈在全局变量中,然后将范围保留在对象所在的位置 定义,全局变量成为悬空指针;尝试去 通过它访问对象是未定义的行为(并调用一个 它上面的非静态成员函数被认为是使用它)。是否 访问来自同一个线程,或者不同的线程不会改变 任何东西。