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

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

1.0 Junior🔥 171 комментариев
#Операционные системы и Linux#Основы Go

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

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

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

Разница между потоком и процессом

Процессы и потоки — это два фундаментально разных уровня параллелизма в операционных системах. Понимание их различий критично для разработки высокопроизводительных систем.

Определения

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

Поток (Thread) Поток — это единица выполнения внутри процесса. Несколько потоков могут существовать в одном процессе и разделять одно адресное пространство, но иметь собственный стек вызовов и регистры.

Основные различия

1. Память и ресурсы

// В контексте Go goroutines (легковесные потоки):
import "runtime"

func main() {
    // Goroutine использует намного меньше памяти, чем OS поток
    fmt.Println("NumGoroutine:", runtime.NumGoroutine())
    
    // ОС процесс требует мегабайты памяти
    // OS поток требует мегабайты памяти (обычно 1-8 МБ)
    // Goroutine требует килобайты памяти (~2-4 КБ)
    
    // Можно создать миллионы goroutines
    for i := 0; i < 1000000; i++ {
        go func() {
            // каждая goroutine очень дешёвая
        }()
    }
}

2. Изоляция

  • Процесс: полная изоляция памяти. Процесс A не может напрямую получить доступ к памяти процесса B.
  • Поток: потоки в одном процессе разделяют память и могут друг друга нарушить.
// Потоки разделяют память
var counter int = 0

func increment() {
    counter++  // две goroutines могут одновременно изменять счётчик!
}

func main() {
    go increment()
    go increment()
    time.Sleep(time.Second)
    fmt.Println(counter)  // может быть 1 или 2 - race condition!
    
    // Решение - использовать синхронизацию
    var mu sync.Mutex
    mu.Lock()
    counter++
    mu.Unlock()
}

3. Создание и управление

  • Процесс: создание дорогое, требует создания нового адресного пространства
  • Поток: создание дешёвое, особенно goroutines в Go
import "os/exec"

// Создание OS процесса - дорого
cmd := exec.Command("ls", "-la")
err := cmd.Run()

// Создание goroutine - очень дешево
go func() {
    // работа
}()

4. Коммуникация

  • Процессы: IPC (Inter-Process Communication) через pipes, sockets, message queues
  • Потоки: прямой доступ к разделяемой памяти (требует синхронизации)
// Goroutines коммуницируют через channels (безопасно)
ch := make(chan int)

go func() {
    ch <- 42
}()

value := <-ch
fmt.Println(value)  // 42

// Или через разделяемую память (требует mutex)
var data = 0
var mu sync.Mutex

go func() {
    mu.Lock()
    data = 42
    mu.Unlock()
}()

mu.Lock()
fmt.Println(data)
mu.Unlock()

5. Надёжность и сбои

  • Процесс: если процесс падает, он не влияет на другие процессы
  • Поток: если поток падает (panic), может привести к падению всего процесса
func main() {
    // Если goroutine panics, может упасть вся программа
    go func() {
        defer func() {
            if r := recover(); r != nil {
                fmt.Println("Recovered:", r)
            }
        }()
        panic("Something went wrong")
    }()
    
    time.Sleep(time.Second)
    fmt.Println("Program continues")
}

Go и Goroutines

Go избежал сложности OS потоков, создав goroutines — легковесные потокоподобные сущности, управляемые runtime. Это дает Go огромное преимущество:

// Миллионы goroutines - нет проблем!
for i := 0; i < 1000000; i++ {
    go handleRequest(i)
}

Таблица сравнения

ХарактеристикаПроцессПотокGoroutine
ПамятьМегабайты1-8 МБ~2-4 КБ
СозданиеДорогоДорогоОчень дешево
ИзоляцияПолнаяМинимальнаяМинимальная
СинхронизацияIPCMutex, semaphoreChannels, Mutex
Макс. количествоСотниТысячиМиллионы

Go goroutines демонстрируют, что можно получить лучшее из обоих миров: безопасность потоков с производительностью и простотой.

В чем разница между потоком и процессом? | PrepBro