Ответ 1
"Спящий"
Вы можете использовать многочисленные конструкции, которые блокируются навсегда, не "съедая" ваш процессор.
Например, a select
без каких-либо case
(и no default
):
select{}
Или получение с канала, где никто ничего не отправляет:
<-make(chan int)
Или получение из канала nil
также блокируется навсегда:
<-(chan int)(nil)
Или отправка по каналу nil
также блокируется навсегда:
(chan int)(nil) <- 0
Или заблокировать уже заблокированный sync.Mutex
:
mux := sync.Mutex{}
mux.Lock()
mux.Lock()
Выход
Если вы хотите предоставить способ выхода, простой канал может это сделать. Предоставьте канал quit
и получите от него. Когда вы хотите выйти, закройте канал quit
, поскольку "операция приема на закрытом канале всегда может начинаться немедленно, давая тип элемента нулевое значение после любого ранее отправленного значения были получены".
var quit = make(chan struct{})
func main() {
// Startup code...
// Then blocking (waiting for quit signal):
<-quit
}
// And in another goroutine if you want to quit:
close(quit)
Обратите внимание, что выдача close(quit)
может прекратить ваше приложение в любое время. Цитата из Spec: Выполнение программы:
Выполнение программы начинается с инициализации основного пакета и последующего вызова функции
main
. Когда возвращается эта функция, программа завершает работу. Он не ждет завершения других (неmain
) goroutines.
Когда выполняется close(quit)
, может действовать последний оператор нашей функции main()
, что означает, что gotoutine main
может вернуться, поэтому программа завершает работу.