В Go есть замечательная языковая функция, называемая «горутина». Однако я иногда скучаю по старому школьному api «thread». Отсутствуют две функции:

  • отменить и дождаться выхода горутины
  • обработчик необработанной паники

Итак, вот что я придумал, крошечная библиотека https://github.com/modern-go/concurrent:

Это очень простая библиотека для прикрепления запущенной горутины к объекту-исполнителю. Один объект-исполнитель может использоваться для управления одной или несколькими горутинами.

Вы можете выбрать

  • Стоп: горутина завершит работу через некоторое время
  • StopAndWait: будем ждать, пока вы не отмените ожидание
  • StopAndWaitForever: будет, пока горутина не завершит работу

Полезно использовать команду «Остановить и подождать», чтобы корректно завершить работу моей службы. Но ждать, не зная, какая горутина блокирует, раздражает.

когда мы устанавливаем InfoLogger, мы можем видеть, кто блокирует

UnboundedExecutor is still waiting goroutines to quit startFrom /home/xiaoju/workspace/src/github.com/modern-go/concurrent/unbounded_executor_test.go:25 count 1
...
goroutine exited
executor stopped

Внутри мы используем номер функциональной строки для идентификации горутины. И каждый жизненный цикл горутины отслеживается, поэтому мы точно знаем, «кто» и «сколько» там еще висит.

Еще мы хотели бы рассказать о том, как справляться с паникой. По умолчанию горутина приводит к сбою процесса. Иногда такое поведение желательно. Иногда это не так. Мы хотели бы сделать поведение «по умолчанию» определяемым пользователем.

определяя concurrent.HandlePanic, мы можем контролировать, как необработанная паника горутины будет обрабатываться глобально. Если мы хотим более детального управления, мы также можем установить HandlePanic на уровне исполнителя.

Надеюсь, вы найдете это полезным, и поставьте мне звезду: https://github.com/modern-go/concurrent