Как убить "func()" в момент времени "go exit1"?

68 views
Skip to first unread message

Aln Kapa

unread,
Jan 23, 2018, 1:24:50 AM1/23/18
to Golang Russian
Добрый день.

Как убить "func()" в момент времени "go exit1"?

package main

import (
 
"fmt"
 
"time"
)


func
TimeoutRead() (err error) {
 defer fmt
.Println("go exit1")
 ch
:= make(chan bool)
 go func
() {
 defer fmt
.Println("go exit2")
 
// тут что то долго читаем
 time
.Sleep(11 * time.Second)
 ch
<- true
 
}()
 
// тут ждем на время чтения
 
select {
 
case <-ch:
 
return
 
case <-time.After(4 * time.Second):
 
return
 
}
 
return
}


func main
() {
 
TimeoutRead()
 
select {
 
case <-time.After(6 * time.Second):
 fmt
.Println("Hello2")
 
}
}


Andrey Velikoredchanin

unread,
Jan 23, 2018, 2:37:13 AM1/23/18
to golang-ru
Если "долго читаем" - операция в цикле, тогда можно сделать булеву переменную и следить за ее состоянием в func(). Соответственно, прерывание будет заключаться в установке ее значения.
Если там долгая системная операция - тут не думаю что можно что-то сделать.

--
Вы получили это сообщение, поскольку подписаны на группу "Golang Russian".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес golang-ru+unsubscribe@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

Daniel Podolsky

unread,
Jan 23, 2018, 3:00:08 AM1/23/18
to gola...@googlegroups.com
короткий ответ - никакого внешнего управления горутинами не предусмотрено.

если вам нужно, чтобы горутина закончилась по сигналу - она должна
сделать это сама.

способов послать горутине сигнал масса. самый идеоматический -
передать в горутину канал, из которого горутина будет пытаться
периодически читать в селекте. в момент, когда пора завершаться, канал
закрывают, и в горутине, наконец, срабатывает чтение.
> --
> Вы получили это сообщение, поскольку подписаны на группу "Golang Russian".
> Чтобы отменить подписку на эту группу и больше не получать от нее сообщения,
> отправьте письмо на электронный адрес
> golang-ru+...@googlegroups.com.

Daniel Podolsky

unread,
Jan 23, 2018, 3:01:15 AM1/23/18
to gola...@googlegroups.com
> Если "долго читаем" - операция в цикле, тогда можно сделать булеву
> переменную и следить за ее состоянием в func(). Соответственно, прерывание
> будет заключаться в установке ее значения.

булеву переменную, которую мы пишем и читаем через atomic, это важно

Aln Kapa

unread,
Jan 23, 2018, 3:10:28 AM1/23/18
to gola...@googlegroups.com
хм. Но если учесть что горутина висит на io.ReadFull (ждет данные) к примеру, как мне ваша переменная поможет?

23 января 2018 г., 11:00 пользователь Daniel Podolsky <onok...@gmail.com> написал:

> Чтобы настроить другие параметры, перейдите по ссылке
> https://groups.google.com/d/optout.

--
Вы получили это сообщение, поскольку подписаны на группу Golang Russian.

Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес golang-ru+unsubscribe@googlegroups.com.
Настройки подписки и доставки писем: https://groups.google.com/d/optout.

Daniel Podolsky

unread,
Jan 23, 2018, 3:24:54 AM1/23/18
to gola...@googlegroups.com
> хм. Но если учесть что горутина висит на io.ReadFull (ждет данные) к
> примеру, как мне ваша переменная поможет?

очевидно, тут вам ничто не поможет

Andrey Velikoredchanin

unread,
Jan 23, 2018, 6:56:18 AM1/23/18
to golang-ru


23 января 2018 г., 11:24 пользователь Daniel Podolsky <onok...@gmail.com> написал:

> хм. Но если учесть что горутина висит на io.ReadFull (ждет данные) к
> примеру, как мне ваша переменная поможет?

очевидно, тут вам ничто не поможет

Да, очевидно. Это второй вариант в том что я описал.

Александр Костриков

unread,
Jan 23, 2018, 10:38:24 AM1/23/18
to Golang Russian
Почему?
Вы ведь только читаете из горутины в цикле.

Daniel Podolsky

unread,
Jan 23, 2018, 10:42:18 AM1/23/18
to gola...@googlegroups.com
> Вы ведь только читаете из горутины в цикле.

если в эту переменную не писать - от нее пользы не будет :)

Alex Lurye

unread,
Jan 23, 2018, 11:46:27 AM1/23/18
to gola...@googlegroups.com
Кошерный способ прерывать дочерние горутины - это использовать контекст (https://godoc.org/context). Его можно делать отменяемым (context.WithCancel). По сути, под капотом там тот же канал, в который подаётся сигнал отмены, но плюс в том, что в отличие от "ручного" канала и atomic-переменных, контекст поддерживается многими библиотеками - сетевыми, базами данных, gRPC и т.д. Контект можно проверять на то, завершён он или нет, при помощи ctx.Err() != nil. У модуля ещё много полезных свойств - в частности, поддерживается иерархия контекстов. Завершив родительский контекст, вы приьбёте и всё, что он породил.

On Tue, Jan 23, 2018 at 7:42 AM Daniel Podolsky <onok...@gmail.com> wrote:
> Вы ведь только читаете из горутины в цикле.

если в эту переменную не писать - от нее пользы не будет :)

--
Вы получили это сообщение, поскольку подписаны на группу Golang Russian.

Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес golang-ru+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages