Golang Channel Initial Contact

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Synchronization between the Goroutine

Goroutine is a lightweight thread implemented at the language level in Golang and can be used to start a new thread just by using go . Multithreading introduces synchronization issues between threads, classic synchronization issues such as producer-consumer issues, the need to use locks at the C,java level, semaphores for shared resource use, and timing control between multithreading, while in Golang there is a channel as a tool for synchronization.

1. Channel to achieve communication between two Goroutine

package mainimport "strconv"import "fmt"func main() {taskChan := make(chan string, 3)doneChan := make(chan int, 1)for i := 0; i < 3; i++ {taskChan <- strconv.Itoa(i)fmt.Println("send: ", i)}go func() {for i := 0; i < 3; i++ {task := <-taskChanfmt.Println("received: ", task)}doneChan <- 1}()<-doneChan}
    • Create a channel, type refers to the make(chan TYPE {, NUM}) data type transferred in the channel, the second parameter is optional and refers to the size of the channel's capacity.
    • To pass data to the channel, CHAN <- DATA CHAN refers to the party that collects the data, which is the data to be transmitted.
    • Start a Goroutine receive the data that main routine sends to the channel, and go func(){ BODY }() create a new thread to run an anonymous function.
    • Reading data from the channel, DATA := <-CHAN and in contrast to passing data to the channel, on the right side of the data delivery arrow is the channel, which graphically shows the data flowing out of the ' tunnel ' into the variable.
    • Notifies the main thread that the task execution is over, Donechan is intended to let main routine wait for this new goroutine to end, showing another feature of the channel, which would block the current routine if the data was read from the empty channel Until there is data that can be read.

The above program is the main routine to another routine sent 3 int type of data, when 3 data is received, the main thread also resumed from the blocking state, and then ended.

2. Do not fall into the "deadlock"

When I first used the channel, I reported "Fatal Error:all Goroutines is asleep-deadlock!" Error, the real code is the following:

package mainimport "fmt"func main() {ch := make(chan int)ch <- 1   // I'm blocked because there is no channel read yet. fmt.Println("send")go func() {<-ch  // I will never be called for the main routine is blocked!fmt.Println("received")}()fmt.Println("over")}

My intention was to send the data from main routine to another routine int, but I ran the above error for 2 reasons:

    • When the current routine sends/receives data to the channel, if the other end does not receive/send accordingly, then the current routine will hibernate.
    • This program's main routine first in the ch <- 1 sleep state, the rest of the program is too late to run, then the channel data will never be read out, you can not wake the main routine, into the "deadlock."

The solution to this "deadlock" is to set the channel capacity of more than 1, then the channel will not because of data input and blocking the main path; Or put the data into the channel's statement after you start a new goroutine.

3. Channel as a signal source for state transfer

I followed MIT's distributed computing course with a prototype for Map-reduce, which was designed to enable a master to assign tasks to a worker: The master server waits for the worker server connection to register, Master assigns the map task and the reduce task to these registered workers, waits for the map task to complete, and then allocates the reduce task for completion.

Initialize a channel which records the process of the map jobs.mapjobchannel: = Make (Chan string)//Start a goroutine t  o Send the NMap (the number of the Map jobs) tasks to the main routine.go func () {for M: = 0; m < NMap; m++ {//Send the "Start a Map job <m>" to the Receiver.mapjobchannel <-"start," + StrConv. Itoa (M)}} ()//Main routine listens on this mapjobchannel for the Map job task information.nmapjobs: = nmap//Process The n Map map Tasks Util they ' re all done.for nmapjobs > 0 {//Receive the Map tasks from the channel.taskinfo: = Strings. Split (<-mapjobchannel, ",") state, Mapno: = taskinfo[0], taskinfo[1]if state = = ' Start ' {//Assign a MAP task with Numbe  R Mapno to a worker.go func () {//Wait-a worker to finish the Map Task.ok, Workno: = Assignjobtoworker ("map", Mapno) if OK {//Send a task finish signal and set the worker ' s state to Idle.mapjobchannel <-"end," + mapnosetworkerstate (wor KNo, "Idle")} else {//Restart this task and set the worker ' s StAte to Finished.mapjobchannel <-"start," + Mapnosetworkerstate (Workno, "Finished")}} ()} else {nmapjobs--}} 

The above is the code I intercepted myself, about using the channel to pass the current map task progress information, with similar signals to mark the current task execution status.

    • When read from the channel to "Start, {num}" to find a free worker to perform the map task, and wait for it to complete, to complete the success of the channel to send "end, {num}" signal, indicating the completion of the task, if failed, resend "start, { NUM} "signal.
    • The number of remaining tasks is reduced by 1 when reading from the channel to "end, {NUM}".
      This signal triggers the way that triggers the master's state transition, and can expand the business process by increasing the signal and signal processing, and can temporarily handle the demand scenario.

MIT Distributed Systems Course

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.