This is a creation in Article, where the information may have evolved or changed.
Go is not the same as other languages, it has supported concurrency from the language level and does not require us to create new threads from the thread library. The channel mechanism in go allows us to not worry too much about locking and concurrency security issues. The channel provides a way to transfer traffic between goroutine.
Today I want to start with a common deadlock error and discuss the characteristics of the channel.
If you run the following program:
var ch = make(chan int)func main() { ch <- 1 <-ch // 没有这行代码也会报同样的错误}
Terminal will report the following error:
fatal error: all goroutines are asleep - deadlock!
Recalling the concept of channel, in general, the channel is goroutine communication between the pipeline, the flow of data in the channel represents the sharing of memory between Goroutine. On the macro level, the channel is a bit like a queue in other languages, followed by FIFO rules.
Channels are divided into unbuffered channels (i.e., unbuffered channel) and buffered channels (buffered channel). For unbuffered channels, the Send and receive messages (receive) for our default channel are blocked (block). In other words, the unbuffered channel is in the suspended state when the message is received and the message is goroutine. Goroutine cannot continue execution unless the other end is ready.
The above procedure is an obvious error example. When the main function executes to CH <-1, Main (also a goroutine) is suspended, and no other goroutine is responsible for receiving messages, and the following sentence <-ch can never be executed, the system is automatically sentenced to timeout return error. All of these threads or processes are waiting for the resource to be released, and we call it a deadlock.
Deadlocks are a very interesting topic, and the common deadlocks are broadly divided into the following categories:
I. Operate the channel only in a single goroutine example.
II. The middle loop of the series channel hangs, for example:
var ch1 chan int = make(chan int)var ch2 chan int = make(chan int)func say(s string) { fmt.Println(s) ch1 <- <- ch2 // ch1 等待 ch2流出的数据}func main() { go say("hello") <- ch1 // 堵塞主线}
CH1 waits for CH2 to leave data, however CH2 does not emit data causing Goroutine to block, the solution is to feed CH2 data:
func feedCh2(ch chan int) { ch <- 2}
III. Non-buffered channel failure:
c, quit := make(chan int), make(chan int)go func() { c <- 1 // c通道的数据没有被其他goroutine读取走,堵塞当前goroutine quit <- 0 // quit始终没有办法写入数据}()<- quit // quit 等待数据的写
Of course, not all non-paired unbuffered channels will get an error:
func say(ch chan int) { ch <- 1}func main() { ch := make(chan int) go say(ch)}
Interestingly, although the say function hangs waiting for the channel to receive the message, the main goroutine is not blocked and the program can terminate automatically after the main function returns.
About the buffer channel will be introduced in the following article, if you have comments please advise.
reference:http://blog.csdn.net/kjfcpua/article/details/18265441
- End -