Go programming Tips--goroutine's elegant control

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

Original: Go programming tips--goroutine's elegant control

GoroutineIs the most important mechanism of the go language, which Goroutine abstracts the complex asynchronous IO calls into synchronous calls, conforms to the normal sequence of human thinking, greatly simplifies the difficulty of IO programming. As with the thread, the Goroutine exit mechanism should be well controlled in order to master the basic usage Goroutine . This paper introduces a kind Goroutine of exit idea.

There Goroutine are usually two cases of blocking:

    1. IO operations, such as the right Socket Read .

    2. channelOperation. The reading and writing of a Chan can be blocked Goroutine .

For Case 1, only the corresponding descriptor needs to be closed, and the blocked Goroutine nature will be awakened.

The focus of the discussion is 2. Concurrent programming, which Goroutine provides a channel mechanism, similar to a pipeline, where the channel writer writes data to the reader and reads the data from it. If there channel is no data in it, the reader will block until there is data, and if the channel data is full, the writer will be blocked by the inability to continue writing the data.

If writer and reader both behave as one and always work throughout the lifetime of the application, Goroutine how do you notify them to terminate before the application is finished? In go, it is not recommended to force termination like the abort thread Goroutine . Thus, abstractly, it is necessary to retain an entry that communicates with writer or reader to inform them of termination.

Let's read reader first. The first thing we can think close of is to use the function to close the reading channel so that you can wake reader and exit. But considering that the close writer is not well handled (because writer tries to write an already close channel, an exception is thrown). Therefore, we need to design an additional read-only channel for notification:

type routineSignal struct {    done <-chan struct{}}

routineSignalShould be generated externally and passed to reader, for example:

func (r *reader)init(s *routineSignal) {    r.signal = s}

In the reader's loop, it can be written like this:

func (r *reader)loop() {    for {        select {        case <-r.signal.done:            return        case <-r.queue:            ....        }    }}

When the need to terminate Goroutine only need to close this extra channel :

close(signal.done)

It looks perfect, and it can handle most of the situation. There is a drawback, though, that we can expect to close wake up and Goroutine exit, but we don't know Goroutine when to complete the exit, because Goroutine there may be some aftercare before the exit, which we need sync.WaitGroup . Retrofit routineSignal :

type routineSignal struct {    done chan struct{}    wg   sync.WaitGroup}

Add a sync. Waitgroup example, in the Goroutine beginning of work, the WG plus 1, Goroutine before exiting, the WG minus 1:

func (r *reader)loop() {    r.signal.wg.Add(1)    defer r.signal.wg.Done()    for {        select {        case <-r.signal.done:            return        case <-r.queue:            ....        }    }}

External, just wait to WaitGroup return:

close(signal.done)signal.wg.Wait()

As long as Wait() the return can be concluded Goroutine .

It is not difficult to deduce that this method can be used for writer. So, to summarize, we created a structure called routinesignal , which contains a Chan to notify goroutine end, including a Waitgroup for Goroutine notifies the outside to complete the cleanup. This way, an instance of this structure gracefully terminates Goroutine , and you can also ensure that Goroutine terminates successfully.

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.