Ответ
В Go существует четкое разделение между внутренним параллелизмом (горутины) и взаимодействием с внешними процессами ОС.
1. Внутренний параллелизм: Горутины (Goroutines)
Вместо прямого управления потоками ОС, Go использует горутины — легковесные потоки, управляемые средой выполнения Go (Go runtime).
-
Создание: Горутина запускается с помощью ключевого слова
go
перед вызовом функции. Это неблокирующая операция.func myTask() { fmt.Println("Работает в отдельной горутине") } func main() { go myTask() // Запуск функции в новой горутине time.Sleep(1 * time.Second) // Даем время горутине выполниться }
-
Ключевые особенности:
- Дешевизна: Начальный стек горутины всего ~2KB, в отличие от потоков ОС (1MB+).
- Планировщик Go: Рантайм Go использует M:N планировщик, который эффективно распределяет M горутин по N потокам ОС. Вам не нужно управлять этим вручную.
- Коммуникация: Для синхронизации и обмена данными между горутинами используются каналы (
chan
) и примитивы синхронизации из пакетаsync
.
2. Взаимодействие с внешними процессами ОС
Для запуска и управления внешними командами и процессами используется пакет os/exec
.
-
Создание:
exec.Command()
создает структуру для запуска внешней команды, но не запускает ее сразу.import ( "fmt" "os/exec" "log" ) func main() { // Подготовка команды `ls -la` cmd := exec.Command("ls", "-la") // Запуск команды и получение ее вывода output, err := cmd.Output() if err != nil { log.Fatal(err) } fmt.Println(string(output)) }
-
Управление: Пакет
os/exec
позволяет управлять стандартными потоками ввода/вывода (stdin
,stdout
,stderr
), ожидать завершения процесса (cmd.Wait()
) и получать его код возврата.
Итог:
- Для параллельных вычислений внутри вашей программы используйте горутины.
- Для запуска и взаимодействия с другими программами в системе используйте
os/exec
.