I saw an example that implements a device similar to a nuclear bomb launch, which still needs to be input to terminate the launch at any time before launching.
Here you can use cahnnel and select to achieve multiplexing.
The use of select is a bit like switch. But unlike switch, a case of select represents a communication operation (send or receive on a channel) and will contain a statement block composed of some statements. Now let's implement this nuclear bomb launcher
package main import ( "fmt" "time" "os" ) func launch() { ("nuclear launch detected") } func commencingCountDown(canLunch chan int) { c := (1 * ) for countDown := 20; countDown > 0; countDown-- { (countDown) <- c } canLunch <- -1 } func isAbort(abort chan int) { (make([]byte, 1)) abort <- -1 } func main() { ("Commencing coutdown") abort := make(chan int) canLunch := make(chan int) go isAbort(abort) go commencingCountDown(canLunch) select { case <- canLunch: case <- abort: ("Launch aborted!") return } launch() }
First print a commencing countdown to start countdown.
Declare an int-type channel variable abort to use as the message semaphore passed to select during cancellation will be introduced later.
Declare an int channel variable canLaunch to be used as the countdown to send the semaphore that can be transmitted. The launch can only be performed when the countdown is over and canLunch has a value.
Use a goroutine to enable a function isAbort for listening for whether there is a stop transmitting signal and pass in the declared channel variable.
isAbort does one thing, monitoring whether there is a standard input input. If there is an input, we will issue a signal that will stop transmitting. We need to send a signal to the abort channel. Here we will launch a -1
Use a goroutine to enable a function for countdown commencingCountDown to start the countdown. Here we reiterate a TICK channel countdown every second. And after the countdown is completed, a signal is sent to the canLunch channel.
Then start executing select. Select will block or execute the specified default when there is no ready channel. Here I did not write default so it will block and listen to two signals, one is canLunch and the other is to stop sending. As long as any signal is received, the following contents of the signal are executed.
Finally run the Lunch function.
In fact, it will not be too confusing to understand the ideas clearly and think about such problems in a concurrent way. Exercising more should make you better. The following article should start gradually starting from the server and connection to implement an im system. Or add more practice.
Added: golang uses select to complete the timeout
I won't say much nonsense, let's just read the code~
timeout := make(chan bool, 1) go func() { (1e9) timeout <- true } () select { case <- ch: //Read data from ch case <-timeout: //Ch has not been written to data, timeout triggers timeout}
func main() { var a chan string a =make(chan string) go sendDataTo(a) go timing() getAchan(10*,a) } func sendDataTo(a chan string) { for { a <- "I am the data of channel a" (1e9 *3) } } //If the data of a cannot be received within a certain period of time, the timeout will be exceededfunc getAchan(timeout , a chan string) { var after <-chan loop: after = (timeout) for{ ("Waiting for data in a, if there is no data after 10 seconds, timeout") select { case x :=<- a: (x) goto loop case <-after: ("timeout.") return } } } func timing() { //Timer, executed once in 10 seconds ticker := (10 * ) for { time := <- ("Timer====>",()) } }
The above is personal experience. I hope you can give you a reference and I hope you can support me more. If there are any mistakes or no complete considerations, I would like to give you advice.