В чем разница между процессом и потоком (thread)?

«В чем разница между процессом и потоком (thread)?» — вопрос из категории Многопоточность, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Процесс и поток — это единицы выполнения, но они работают на разных уровнях абстракции и изоляции.

Процесс

  • Определение: Изолированный экземпляр выполняемой программы. Каждый процесс имеет собственное виртуальное адресное пространство в памяти, код, данные, системные ресурсы (открытые файлы, сокеты) и как минимум один поток.
  • Изоляция: Процессы полностью изолированы друг от друга на уровне ОС. Один процесс не может напрямую получить доступ к памяти или ресурсам другого (для обмена данными нужны механизмы IPC — каналы, shared memory, сообщения).
  • Создание: Создание процесса (fork/exec) — операция тяжелая, так как ОС должна выделить и настроить новое адресное пространство, таблицы страниц и т.д.
  • Пример: Запуск браузера и текстового редактора — это два разных процесса.

Поток (Thread)

  • Определение: Легковесная единица выполнения внутри процесса. Все потоки одного процесса разделяют его адресное пространство и ресурсы (глобальные переменные, открытые файлы).
  • Изоляция: Каждый поток имеет свой собственный стек вызовов и регистры процессора, но общую кучу (heap) и статическую память.
  • Создание: Создание потока значительно легче, чем процесса, так как не требуется настройка нового адресного пространства.
  • Пример: В веб-сервере один процесс может создавать множество потоков для одновременной обработки запросов от разных клиентов.

Сравнительная таблица

Характеристика Процесс Поток (Thread)
Изоляция Полная (собственная память). Ограниченная (общая память, отдельный стек).
Создание/уничтожение Медленно, ресурсоёмко. Быстро, легковесно.
Коммуникация Сложно (IPC: pipes, sockets). Просто (общие переменные).
Отказоустойчивость Высокая: падение одного процесса не затрагивает другие. Низкая: падение потока может "убить" весь процесс.
Параллелизм Межпроцессный (на разных ядрах CPU). Внутрипроцессный (на разных ядрах CPU).

Практический пример на C

// Запуск нового процесса (например, открытие Блокнота)
using System.Diagnostics;
Process.Start("notepad.exe");

// Создание и запуск потока (старый API Thread)
Thread workerThread = new Thread(() =>
{
    // Этот код выполняется в фоновом потоке
    Console.WriteLine($"Поток {Thread.CurrentThread.ManagedThreadId} работает.");
    Thread.Sleep(1000);
});
workerThread.Start();

// Более современный подход — Task (работает с пулом потоков)
Task.Run(() =>
{
    Console.WriteLine($"Задача выполняется в потоке {Thread.CurrentThread.ManagedThreadId}.");
});

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