Ответ
Да, все потоки, созданные в рамках одного процесса, имеют доступ к глобальным (статическим) переменным, так как они находятся в общем адресном пространстве. Однако такой несинхронизированный доступ приводит к состоянию гонки (race condition). Для безопасной работы с общими данными необходимо использовать механизмы синхронизации.
Основные подходы в C++:
- Мьютексы (
std::mutex): Гарантируют эксклюзивный доступ. - Атомарные операции (
std::atomic): Позволяют выполнять операции чтения-записи без блокировок для примитивных типов. - Условные переменные (
std::condition_variable): Для координации потоков по событиям.
Пример с std::mutex и RAII-оберткой std::lock_guard:
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
int global_counter = 0;
std::mutex global_counter_mutex;
void increment_global(int iterations) {
for (int i = 0; i < iterations; ++i) {
// Автоматически блокирует и разблокирует мьютекс
std::lock_guard<std::mutex> lock(global_counter_mutex);
++global_counter; // Критическая секция защищена
}
}
int main() {
std::thread t1(increment_global, 100000);
std::thread t2(increment_global, 100000);
t1.join();
t2.join();
// Без мьютекса результат был бы меньше 200000
std::cout << "Final counter value: " << global_counter << std::endl; // 200000
return 0;
}
Почему это важно: Без синхронизации операция ++global_counter (которая состоит из чтения, изменения и записи) может быть прервана другим потоком, что ведет к потере обновлений и неопределенному поведению программы.