go coroutine scheduling

This article does not discuss through the channel, sync and other specific wording to achieve coroutine scheduling, dispatching simply talk coroutine this child.

Non-preemptive scheduling

Coroutine go scheduling language is a non-preemptive scheduling, where a non-preemptive? Let's say preemptive.

We know that the operating system thread scheduling, use the round-robin scheduling each thread way, when the time required to piece the thread from the thread A B, regardless of what state the thread A will first stopped. This will often scheduling a situation in which A thread is doing a thing to do half the time, time to, in order to ensure that the next time slice turn it, we can just continue to do the thing, thread a need for the current state into the register, then the problem will be obvious, keep a register of this operation is very time-consuming, this is a preemptive shortcomings.

The non-preemptive go of it, no one refers to the force stopped a coroutine to perform another coroutine, coroutine will take the initiative to give up the CPU . How to make a law? Nature is not free to make, so that when the purpose is to avoid the need to switch to a pile of coroutine state into the register, so coroutine will finish one thing at a time to let the CPU, so you do not need to save anything up .

Compile-time scheduling

So how do you know when to finish coroutine one thing it? If the runtime to determine this child, obviously require additional costs, so go language is determined at compile time, which means that when the program is running, how to switch between coroutines, at compile time planned a . This is the language level to achieve the benefits go coroutine from arising.

Switching point

Here are several coroutine possible handover of:

  • io, such as print, print finish, the finish can be considered a thing
  • Function calls can be understood as to call functions that have to do another thing children, so this time you can switch
  • channel, sync, runtime.Gosched (), which has always been more than coroutine with something, do not say

Note that the above are several, but the switch may not necessarily switch, that is not always finished print will certainly switch to another thread go, go will determine a more appropriate time to switch the actual code.

This can actually see a small example, the following code, opened 10 coroutine, but in fact is 11, we must not forget the main coroutine is a coroutine , it is very important, because once the main coroutine exit, other coroutine will also be killed, which is why the following program, we let the main coroutine sleep one second, if you do not sleep, do not wait for the main coroutine time slices give it away, the main coroutine End run directly out of the 10 other co-routines will not debut chance.

package main

import (
	"fmt"
	"time"
)

func main()  {
	for i := 0; i < 10; i++ {
		go func(i int) {
			for {
				fmt.Println(i)
			}
		}(i)
	}
	time.Sleep(time.Second)
}

The results of running the program a lot, we only last a short specimens, it is enough to explain the problem.

After you can see, the interception of this, there was a coroutine switch, the switch occurred after the printing of 3 coroutine been printed more than 3, that is, coroutine switching does occur in the print, but not every print will be switched. In fact, well understood, although go coroutine switching thread switching overhead is smaller than, but after all, there are overhead, we still can not say cut to cut.

We change the kinds of writing and try again.

package main

import (
	"time"
)

func main()  {
	for i := 0; i < 10; i++ {
		go func(i int) {
			for {
				i++
			}
		}(i)
	}
	time.Sleep(time.Second)
}

This program is also open 10 coroutine, different time, coroutine there is no print, or do not go any language compiler can be regarded as a point coroutine switch, so the result of this operation is, forever will not quit, because as long as one into the coroutine, would have been i ++, I will not switch. The actual writing code, we naturally want to avoid write this.

Thread

Finally, the default language would like to talk threads go way, we know that a thread can have multiple coroutines, then when we actually run multiple processes at the same time the Association, in the end it will be a few threads?

The answer is, the CPU has several nuclear, use several threads . We know that, although single-core to run multiple threads, multiple concurrent threads are not true, but in order to run in the CPU scheduling. For the go, the thread scheduling is meaningless, because the go has to do more coroutine appropriate scheduling from the language level. Therefore, there are 1000 concurrent coroutines even a program, if only 4-core CPU, the program up and running will only use up to four threads.

Published 39 original articles · won praise 25 · views 120 000 +

Guess you like

Origin blog.csdn.net/u013536232/article/details/104892205