当前位置:网站首页>Golang--- concurrent goroutine

Golang--- concurrent goroutine

2022-06-09 04:08:00 It artist rookie

goroutine With threads

Stacks that can grow

OS Threads ( Operating system threads ) Generally, there is fixed stack memory ( Usually it is 2MB), One goroutine At the beginning of its life cycle, there are only a few stacks ( Typically 2KB),goroutine The stack of is not fixed , He can grow and shrink as needed ,goroutine The stack size limit of can be reached 1GB, Although it's rare to use this big . So in Go One hundred thousand at a time goroutine It's OK, too .

goroutine Dispatch

GPM yes Go Language runtime (runtime) Realization of level , yes go Language itself to achieve a set of scheduling system . Different from operating system scheduling OS Threads .
1.G Well understood. , That's it. goroutine Of , Except for the storage book goroutine Out of information And where P Binding and other information .
2.P Manage a group of goroutine queue ,P It will store the current goroutine Running context ( A function pointer , Stack address and address boundary ),P I will manage myself goroutine Do some scheduling in the queue ( For example, take up CPU For a long time goroutine Pause 、 Run the following goroutine wait ) When your queue is consumed, go to the global queue to get , If the overall queue is also consumed, it will go to other P We're in line for a mission .
3.M(machine) yes Go Runtime (runtime) Virtual to the kernel thread of the operating system , M The relationship with kernel thread is generally one-to-one mapping , One groutine In the end, it's to put M Performed on ; P And M It's usually one-to-one . Their relationship is :
P Manage a group of G Mounted on M Up operation . When one G For a long time in a M Upper time ,runtime It will create a new one M, Blocking G Where P Will put the others G
It's on the new M On . When the old G When the block is complete or thought dead Recycle the old M.

P The number of is through runtime.GOMAXPROCS Set up ( Maximum 256),Go1.5 Number of physical threads after version .
When the amount of concurrency is large, it will increase a little P and M, But not too much , Switching too often is not worth it .

Single thread scheduling ,Go The advantages of language over other languages are OS Threads are created by OS Kernel to schedule ,goroutine It is from Go Runtime (runtime) It's scheduled by its own scheduler , This scheduler uses a device called m:n Scheduling Technology ( Reuse / Dispatch m individual goroutine To n individual OS Threads ). One of the main features is goroutine The scheduling of is done in user mode , It doesn't involve frequent switching between kernel state and user state , Including memory allocation and release , All of them maintain a large memory pool in user mode , Don't call the system directly malloc function ( Unless the memory pool needs to change ), Cost to schedule OS Threads are much lower . On the other hand, it makes full use of multi-core hardware resources , Approximate a number of goroutine On the physical thread , Plus itself goroutine It's super lightweight , All of the above guarantees go Scheduling performance .
Reference material

stay main A single coroutine in a function

func hello() {
    
    fmt.Println("Hello Goroutine!")
}
func main() {
    
    go hello()
    fmt.Println("main goroutine done!")
}

result : Only print main goroutine done!
reason :

  1. Creating a collaboration takes time
  2. When the program starts ,Go The program will be main() Function to create a default goroutine. When main() When the function returns goroutine It's over , All in main() Function goroutine It will end together

solve : When main() When the function returns goroutine It's over , All in main() Function goroutine It will end together

func main() {
    
    go hello() //  Start another goroutine To carry out hello function 
    fmt.Println("main goroutine done!")
    time.Sleep(time.Second)
}

func TestOrder(t *testing.T)  {
    
	//  Together, write 
	go func() {
    
		i := 0
		for {
    
			i++
			fmt.Printf("new goroutine: i = %d\n", i)
			time.Sleep(time.Second)
		}
	}()
	i := 0
	for {
    
		i++
		fmt.Printf("main goroutine: i = %d\n", i)
		time.Sleep(time.Second)
		if i == 2 {
    
			break
		}
	}
}

result : It will also carry out
 Insert picture description here

原网站

版权声明
本文为[It artist rookie]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/160/202206090407035208.html