This is a creation in Article, where the information may have evolved or changed.
Today, we introduce the concurrency mechanism of the go language and the CSP concurrency model it uses.
CSP Concurrency model
The CSP model was proposed in the 70 's to describe the concurrency model of two independent concurrent entities communicating via a shared communication channel (pipeline). Channel in CSP is the first class of objects that does not focus on the entity that sends the message, but on the channel used to send the message.
Golang CSP
Golang is to borrow some concepts of CSP model to implement concurrent theory support, in fact, the go language does not, completely realize the CSP model of all the theory, just borrowed the process and channel two concepts. Process is the performance of the go language is that goroutine is the actual concurrent execution of entities, each entity is through channel communication to achieve data sharing.
Channel
The concept of channel in CSP is used in Golang. Channel is created separately and can be passed between processes, its communication pattern is similar to Boss-worker mode, an entity by sending messages to the channel, and then listen to the Channel entity processing, two entities are anonymous, This realizes the decoupling between entities, where the channel is a synchronous message is sent to the channel, and ultimately must be consumed by another entity, in the implementation of the principle is actually a blocking message queue.
Goroutine
Goroutine is an entity that is actually executing concurrently, with the underlying implementation of concurrency (coroutine), coroutine is a user thread that runs in the user state, similar to the Greenthread,go bottom-up choice to use coroutine because, It has the following characteristics:
- User space avoids the cost of switching between the kernel state and the user state
- Can be scheduled by language and framework layer
- Smaller stack space allows creating a large number of instances
You can see that the second user-space thread's schedule is not done by the operating system, as the Greenthread used in Java 1.3 is uniformly dispatched by the JVM (after Java has been changed to kernel threads) and fiber in Ruby (semi-coprocessor) is needed in the re-scheduling, and Goroutine is at the Golang level to provide the scheduler, and the network IO Library is encapsulated, shielding the complex details, to provide unified syntax keyword support, simplifying the cost of concurrent program writing.
Goroutine Scheduler
As mentioned in the previous section, Golang uses goroutine as the smallest execution unit, but the execution unit is still in the user space, which is actually finally executed by the processor or the kernel thread, and the user thread and kernel thread are dispatched as follows:
- N: More than 1 user threads corresponding to one kernel thread
- 1:11 user threads corresponding to one kernel thread
- M:N user thread and kernel thread are many-to-many correspondence
Golang achieves high-efficiency m:n thread correspondence by providing Goroutine with a language level scheduler.
Dispatch schematic
In the figure
- M: Is kernel thread
- P: Is the scheduling coordination, used to coordinate the execution of M and G, kernel threads only get p in order to continue the execution of goroutine, generally by limiting the number of p to control the concurrency of Golang
- G: Is the goroutine to be executed, including the stack space of this goroutine
- GN: The gray background of GN is already suspended goroutine, they are added to the execution queue, and then need to wait for network IO Goroutine, when p through Epoll query to a specific FD, will be re-dispatched the corresponding, is suspended goroutine.
Golang in order to dispatch the fairness, in the scheduler added steal working algorithm, in a p own execution queue, after processing, it will first go to the global execution queue to steal g to process, if not, see the other P's execution queue to rob G to handle.
Summarize
Golang implements the CSP concurrency model as a concurrency base, and the underlying uses goroutine as the concurrency entity, goroutine very lightweight to create hundreds of thousands of entities. Inter-entity through the channel continue anonymous message delivery decoupling, at the language level to achieve automatic scheduling, so that many internal details, to provide simple syntax keywords, greatly simplifying the thinking of concurrent programming and management of the complexity of threading.