Что произойдет, если я вызову функцию-член объекта из другого потока?

Если у меня есть объект С++, созданный в основном потоке, а затем запустите другой поток, и из этого потока я вызываю публичную функцию-член объекта, который я создал, что происходит?

Разве это не так, если публичная функция имеет параметры или манипулирует частными членами объекта?

Ведет ли он себя по-разному на windows, linux или mac os?

Что произойдет, если объект создан в стеке?

Ответ 1

Имеются две точки:

  • сначала, как обычно, вам нужно убедиться, что время жизни экземпляра превышает продолжительность его использования.
  • во-вторых, доступ к переменным в многопроцессорных потоках необходимо синхронизировать, чтобы предотвратить условия гонки.

Что все люди.

Ответ 2

  • Каждый поток имеет собственный стек и, следовательно, вы можете иметь одновременные потоки выполнения. Это ваша обязанность сделать объект потокобезопасным.

  • Это не имеет значения. Тем не менее, частные члены являются кандидатами на условия гонки.

  • Если вы создаете объект в стеке, он не будет доступен из другого потока.

Ответ 3

Если у меня есть объект С++, созданный в основном потоке, а затем запустите другой поток, и из этого потока я вызываю публичную функцию-член объекта, который я создал, что происходит?

Это зависит от времени жизни объекта.

Если объект создается в куче (динамическая память с использованием new), то другой поток будет обращаться к членам объекта правильно (если не считать условий гонки), если время жизни объекта не закончилось вызовом delete в первая нить.

Если объект создается в стеке (локально) в первом потоке, тогда вы будете иметь * Undefined Behavior *, если время жизни созданного объекта закончилось до обращения во второй поток.

Почему вы можете получить доступ к объекту в стеке во втором потоке?

Каждый поток имеет свой собственный стек, и если объект, созданный в стеке потока, не будет действительным и живым, вы попытаетесь получить доступ к адресу, которое не указывает на какой-либо действительный объект во втором потоке. Обратите внимание: каждый процесс имеет адресное пространство, и все потоки одного и того же процесса имеют одно и то же адресное пространство, поэтому адрес переменной можно получить во втором потоке. Однако вам необходимо убедиться, что адрес содержит допустимый объект.

Разве это отличается, если публичная функция имеет параметры или управляет частным членом объекта?

Спецификаторы доступа и многопоточность не связаны вообще.
Те же правила спецификатора доступа применяются во всех потоках.

Ведет ли он себя по-разному на windows, linux или mac os?

Ответ на #1 гарантирован на всех операционных системах.

Ответ 4

По сравнению с исходным поведением не должно быть различий при создании в куче. Однако, конечно, есть некоторые преступники, обычно известные под термином "безопасность потоков". Если вы обращаетесь к одному и тому же элементу из разных потоков, вы должны соблюдать, что доступ к тем же ресурсам не приводит к "состоянию гонки".

Чтобы избежать условий гонки, вы можете использовать различные "блокировки", например, мьютексы и т.д. При использовании объектов блокировки есть другой виновник: опасность "взаимоблокировок", если два аксессуара ждут друг друга и первоначальный замок никогда не освобождается.

Ответ 5

Он будет работать отлично. Объекты не принадлежат ни одному конкретному потоку и могут одинаково хорошо вызываться из любого места.

Однако, и это важно, вызов функции-члена в двух потоках одновременно вызовет проблемы, когда вы обновляете некоторые данные в одном потоке, читая их в другом. Вам нужно либо упорядочить свой код, чтобы убедиться, что этого не произойдет, либо убедитесь, что ваши потоки координируют доступ (скорее всего, с использованием мьютекса)

Ответ 6

Что происходит, так это то, что происходит, если вы вызываете это из того же нить. Выполняется тот же машинный код. Единственный потенциал разница в том, что вы можете иметь несколько потоков, обращающихся к объекту в в то же время; это вам, чтобы защитить от этого (по крайней мере, если потоков изменяет объект, иначе защита не будет необходимо).

В случае объекта в стеке вы должны учитывать срок службы проблемы, но это так или иначе; сохранить указатель на объект на стек в глобальной переменной, затем оставьте область, в которой объект был и глобальная переменная становится оборванным указателем; пытаясь доступ к объекту через него - это поведение undefined (и вызов нестатическая функция-член на ней рассматривается с ее помощью). Будь то доступ из одного потока или другой поток не изменяется что-нибудь.