Ответ
Поток (thread) — это наименьшая единица выполнения, которую может планировать операционная система. В рамках одного процесса может существовать множество потоков, которые разделяют его виртуальное адресное пространство (глобальные переменные, куча, открытые файлы), но имеют собственные стеки вызовов и регистры процессора.
Зачем нужны потоки в C++?
- Параллелизм: Использование нескольких ядер CPU для ускорения вычислений.
- Отзывчивость: Выполнение длительных операций (например, I/O) в фоновом потоке, не блокируя основной поток пользовательского интерфейса.
- Асинхронная обработка: Одновременное обслуживание множества сетевых подключений или запросов.
Базовый пример с std::thread (C++11 и выше):
#include <iostream>
#include <thread>
#include <chrono>
void threadFunction(int id) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "Hello from thread #" << id << " (ID: "
<< std::this_thread::get_id() << ")" << std::endl;
}
int main() {
std::cout << "Main thread ID: " << std::this_thread::get_id() << std::endl;
std::thread t1(threadFunction, 1); // Создание и запуск потока
std::thread t2(threadFunction, 2);
// Основной поток ждёт завершения t1 и t2
t1.join();
t2.join();
std::cout << "Both threads finished." << std::endl;
return 0;
}
Критически важные моменты:
- Синхронизация: Так как потоки разделяют память, необходим контроль доступа к общим данным для предотвращения состояний гонки (race conditions). Для этого используются:
std::mutex,std::lock_guard,std::unique_lockstd::atomicтипы- Условные переменные (
std::condition_variable)
- Управление жизненным циклом: Поток должен быть либо присоединён (joined) с помощью
join()(основной поток ждёт его завершения), либо отсоединён (detached) с помощьюdetach()(поток выполняется самостоятельно). Невыполнение этого требования до разрушения объектаstd::threadприводит к вызовуstd::terminate. - Проблемы: Взаимные блокировки (deadlocks), инверсия приоритетов, ложное разделение кэша (false sharing).