← Назад к вопросам

Все ли потоки имеют доступ к глобальной переменной

1.3 Junior🔥 151 комментариев
#Многопоточность и синхронизация

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Доступ потоков к глобальным переменным

Да, все потоки в одном процессе имеют доступ к глобальным переменным. Это фундаментальное свойство многопоточного программирования — все потоки одного процесса работают в едином адресном пространстве и, следовательно, могут читать и изменять одну и ту же глобальную переменную.

Как это устроено

Когда ОС создает новый поток, она:

  • Выделяет собственный стек для каждого потока
  • Выделяет собственный стек локальных переменных и буфер вызовов
  • НЕ дублирует глобальные переменные — все потоки видят одну копию
  • Предоставляет доступ к heap, где находятся глобальные данные

Таким образом, глобальные переменные находятся в сегменте .data или .bss программы и доступны всем потокам.

Пример

#include <iostream>
#include <thread>
#include <mutex>

int global_counter = 0;  // Глобальная переменная
std::mutex mtx;          // Для синхронизации

void increment_counter(int id) {
    for (int i = 0; i < 1000; ++i) {
        std::lock_guard<std::mutex> lock(mtx);
        global_counter++;  // Все потоки видят эту переменную
        std::cout << "Thread " << id << " incremented to " << global_counter << std::endl;
    }
}

int main() {
    std::thread t1(increment_counter, 1);
    std::thread t2(increment_counter, 2);
    std::thread t3(increment_counter, 3);
    
    t1.join();
    t2.join();
    t3.join();
    
    std::cout << "Final counter: " << global_counter << std::endl;  // 3000
    return 0;
}

Все три потока (t1, t2, t3) обращаются к одной и той же переменной global_counter.

Критические проблемы: Race Conditions

Хотя все потоки имеют доступ, это создает опасность race conditions — когда несколько потоков одновременно изменяют переменную без синхронизации:

void unsafe_increment() {
    global_counter++;  // НЕБЕЗОПАСНО!
    // Операция разбивается на: load, increment, store
    // Между ними может вклиниться другой поток
}

Решение: Синхронизация

Mutex (взаимное исключение)

std::mutex mtx;
{
    std::lock_guard<std::mutex> lock(mtx);
    global_counter++;  // Только один поток за раз
}

Atomic переменные

std::atomic<int> global_counter(0);
void safe_increment() {
    global_counter++;  // Атомарная операция, потокобезопасна
}

thread_local (локальная копия для каждого потока)

thread_local int thread_local_counter = 0;  // Каждый поток имеет свою копию
void thread_safe_increment() {
    thread_local_counter++;  // Нет race condition
}

Важные моменты

  1. Видимость: Изменения одного потока в глобальной переменной видны другим потокам
  2. Порядок операций: Без синхронизации порядок выполнения операций разных потоков непредсказуем
  3. Кэширование: Процессор может кэшировать значения, поэтому используйте volatile (в старом коде) или std::atomic
  4. Memory barriers: При работе с мьютексами автоматически устанавливаются barriery памяти

Итог

Да, все потоки имеют доступ к глобальным переменным в одном процессе. Но использовать этот доступ без синхронизации опасно. Для безопасной работы используйте std::mutex, std::atomic или thread_local переменные.

Все ли потоки имеют доступ к глобальной переменной | PrepBro