如何存储goroutine的标识,以便以后可以停止使用

时间:2019-03-26 23:58:41

标签: go

我正在尝试创建多个goroutine,并使它们并发运行。然后,当有请求进入时,我想识别其中一个,并仅停止该特定的goroutine,其余的继续进行

文件1

mm := remote_method.NewPlayerCreator()

mm.NewPlayer("Leo", "Messi")

// Lets just assume that the method call starts a bot which starts playing football

mm.NewPlayer("Cristiano", "Ronaldo")

mm.StopPlayer("Leo", "Messi")

文件2

package remote_method

type PlayerCreator struct {
        playerNameChannelNumberMap (map[Player](chan int))
}

type Player struct {
        firstName, lastName string
}

func NewPlayerCreator() DeclaredType {
        var nameChannelMap (map[Player](chan int))
        m := PlayerCreator{nameChannelMap}
        return m
}

func (mm NewPlayerCreator) NewPlayer(firstName string, lastName string) {
     // Update the playerNameChannelNumberMap to add this new Player in the map
     // Since maps are basically called by reference, the map withe the file 1 should be updated or should it ?
     // Call to a goroutine that would create a new player and the player keeps on running in an infinite loop
     // I can add the goroutine code in this method and not create a new method for the goroutine, if it makes more sense like this
}

func (mm NewPlayerCreator) StopPlayer(firstName string, lastName string) {
     // Find the player channel in the map and send a done signal on receiving which it exits
     // Remove the player entry from the map
}

做这种事情的最著名的实践是什么? TIA

1 个答案:

答案 0 :(得分:4)

简短的回答是“你不能”。 Goroutines不像Unix进程或线程。没有PID或线程ID。

您可以通过在主例程和goroutine之间共享的通道中编写一条消息来终止goroutine,告诉您您希望它消失,而不是自己强行终止它。

我不会复制https://blog.golang.org/pipelines中的整个文章; 您最好在那儿阅读。重点:

  • 您可以通过与Goroutine共享频道来取消它(通常命名为done)。您在此频道上发送的实际类型无关紧要。
  • 当您要发送“所有人都关闭”消息时,请关闭done频道。这会导致在通道上进行的任何读取都立即以该通道类型的零值实例成功,从而有效地向每个读取该通道的goroutine广播了一个“停止”信号。
  • goroutine的核心是一个select循环,该循环检查任何输入通道和done通道上的可用输入。通道关闭后,done通道已准备好输入,并且goroutine会清理并退出。

context类型总结了这一点以及许多其他优点。阅读https://blog.golang.org/context文章将为您提供有关使用上下文控制goroutine的更多详细信息。