Как стать автором
Обновить

Комментарии 12

Идеоматичный мьютекс делается так:

mu.lock

defer mu.unlock

<тут операции под мьютексом, он разблокируется при выходе из зоны видимости благодаря defer>

А есть в GO классические коррутины? И есть ли там конкурентность вообще?

А есть в GO классические коррутины?

Смотря что вкладывать в понятие космических корутин.

И есть ли там конкурентность вообще?

Есть. И автор статьи на протяжении всей статьи её описывает.

Насколько я понял смысл статьи, то описывается мнонопотосность. Ну или то, что в Питоне ближе к мнонопотосности.

Ассинхронность, конкурентность в Питоне - это про цикл событий и "тики" этих событий. Когда все выполняется в одном потоке.

Что же до корутин, возможность функции передать управление и запомнить свое состояние. Есть ли это в го

А, ты имеешь ввиду async/await, если я правильно понял. Нет, этот паттерн в Го не реализован. Хотел бы я сказать что он тут и не нужен, но вот мне порой его недостаёт, особенно когда приходится резко перепрыгнуть с того же Питона на Го.

думал только меня это восхитило))))) за столько лет первый раз услышал такое определение. если б кто спросил на собесе про мертвые замки, то я б точно не сообразил что это про обычные deadlocks

не очень понял фразу "Горутина состоит из 70 в коде" - 70 чего? полей? байт? чего-то еще?

Перед отправкой в канал проверяйте, не закрыт ли он уже

Интересно, как?

Перед/совместно с чтением понимаю, но как проверить перед записью, не читая?

Можно перехватывать панику при записи в закрытый канал. Но это плохая практика.

func main() {
	func() {
		defer func() {
			if r := recover(); r != nil {
				fmt.Println("Recovered. Error:\n", r)
			}
		}()
		ch := make(chan struct{}, 1)
		close(ch)
		ch <- struct{}{}
	}()
	fmt.Println("done")
}

Да никак конечно, ерунда написана. Люди любят потереть за горутины и каналы (особенно на собесах), но на практике их по назначению (передача значений, а не сигнализации) почти никто не использует. Идея по сути простая: та горутина, которая пишет в канал, отрабатывает полностью (записывает всё, что у неё было) и закрывает канал. Всё, никаких проверок. Если есть fan-out (горутина, которая порождает горутины, записывающие в канал), то это она следит за тем, чтобы все порождённые горутины успели записать или, ещё лучше, переиспользуем этот канал всё время жизни программы и не закрываем его никогда. От утечки одного канала (в отличии от паники посреди работы) ничего страшного не будет.

func operation(ch chan<- string) {
    // Имитация длительной операции
    time.Sleep(2 * time.Second)
    ch <- "результат операции"
}

func main() {
    ch := make(chan string)
    go operation(ch)

    select {
    case res := <-ch:
        fmt.Println(res)
    case <-time.After(1 * time.Second):
        fmt.Println("Тайм-аут операции")
    }
}

Автор, в данном примере есть потенциальная утечка горутины. Понятно, что в данном случае у вас выход из программы сразу происходит, но для людей, читающих ваш пример, может создастся впечатление, что так нужно делать всегда, независимо от контекста.

Я бы добавил небольшую пометку о том, что тут будет "повисшая" горутина: и она будет висесть, пока из канала не прочитают.

Либо, можно было бы этот пример реализовать через буферизованный канал с величиной буфера '1', тогда рутина не повиснет на 4ой строчке.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий