如果goroutine涉及用户空间线程,阻塞操作是否可以导致整个线程的上下文切换? [英] If goroutines involve userspace threads, can a blocking operation leads to context switch of the entire thread?

查看:104
本文介绍了如果goroutine涉及用户空间线程,阻塞操作是否可以导致整个线程的上下文切换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉,这个问题太愚蠢了.我正在阅读goroutines的详细信息此处.根据该页面的内容,它说 Goroutines被多路复用到少量的OS线程上,而不是1:1映射中,据我所知,我所能想到的是,产生的OS线程数,其中可能使用了用户空间线程或协程.这样对吗?如果是这样,那么我举一个例子,如果一个程序克隆了4个OS线程,其中有多个用户空间线程,并且所有这4个线程中恰好有一个阻塞操作以及非阻塞操作,那么OS是否会调度程序上下文切换所有这些线程,因为用户空间线程对OS线程不透明?

Apologies if this question is too stupid. I was reading through the details of goroutines Here. According to that page, it says Goroutines are multiplexed onto a small number of OS threads, rather than a 1:1 mapping by which, all I could think of with my limited knowledge was, there are a limited number of OS threads spawned, inside which, it may be using userspace threads or coroutines. Is this correct? And if so, if I may take an example, if a program clones 4 OS threads inside which there are multiple userspace threads, and there happen to be a single blocking operation inside all these 4 threads along with non-blocking operations, will the OS scheduler context-switch all these threads, as the userspace threads are not transparent to the OS threads?

出于好奇,是否有可能使用goroutines的C实现,这可以帮助理解内部原理?

Out of curiosity, is there a possible C implementation of goroutines, which could help understand the internals?

推荐答案

下面是阅读 Goroutine在所谓的逻辑处理器"(不是物理处理器)中运行.这些逻辑处理器中的每一个都绑定到一个OS线程.

Goroutines run within what are called "logical processors"(NOT physical processors). Each of these logical processors are bound to a single OS thread.

Go 1.5之后,逻辑处理器的数量等于可用物理处理器的数量.

After Go 1.5, the number of logical processors equals the number of available physical processors.

Go调度程序智能地调度每个逻辑处理器上的多个goroutine的运行

The Go scheduler intelligently schedules the running of multiple goroutines on each of these logical processors

粗略图如下:-

OS线程------逻辑处理器------ Goroutine 1,Goroutine 2 ..... Goroutine n

OS Thread ------ Logical Processor ------ Goroutine 1, Goroutine 2..... Goroutine n

现在,很可能其中一个Goroutine会进行阻塞系统调用.发生这种情况时,

Now, it is very likely that one of the Goroutines makes a blocking system call. When this happens,

  1. 进行阻塞调用的OS线程和Goroutine是与逻辑处理器分离

  1. The OS thread and the Goroutine that made the blocking call are detached from the logical processor

此逻辑处理器现在没有操作系统线程.

This logical processor now has no OS thread.

Go调度程序创建一个新的OS线程,并将其附加到逻辑处理器.附加到逻辑处理器的其余goroutine现在可以继续运行.

The Go scheduler creates a new OS thread, and attaches it to the logical processor. The remaining goroutines that were attached to the logical processor, now continue to run.

分离的goroutine及其关联的OS线程继续阻塞,等待syscall返回.

The detached goroutine and the OS thread it is associated with continue to block, waiting for the syscall to return.

当系统调用返回时,goroutine将重新附加到其中一个逻辑处理器,并置于其运行队列中.

When the system call returns, the goroutine is re-attached to one of the logical processors, and is placed in its run queue.

操作系统线程被保留以备将来使用".我猜它已添加到某种线程池中.

The OS thread is "put aside for future use". I am guessing it is added to some sort of thread pool.

如果goroutine进行网络I/O调用,则其处理方式略有不同.

If the goroutine makes a Network I/O call, it is handled in slightly different way.

goroutine与逻辑处理器分离,并移至集成网络轮询器.轮询器说I/O操作准备就绪后,goroutine将重新附加到逻辑处理器上进行处理.

The goroutine is detached from the logical processor, and is moved to the integrated network poller. Once the poller says the I/O operation is ready, the goroutine is re-attached to the logical processor to handle it.

-现在,回答您的问题:-)

-- Now, to answer your question :-)

我不是专家,但这是我根据上面所说的会发生的事情.

I'm not an expert, but this is what I think will happen, based on what was stated above.

由于4个OS线程中的每个goroutine进行了阻塞的系统调用,因此所有4个线程将与它们的逻辑处理器分离,并将继续阻塞直到系统调用返回.这4个OS线程将与进行阻塞syscall的各个goroutine关联.

Since one goroutine on each of the 4 OS threads have made a blocking syscall, all 4 threads will be detached from their logical processors, and will continue to block until the syscall(s) return. The 4 OS threads will be associated with the respective goroutines that made the blocking syscall.

现在,这将导致4个逻辑处理器(以及连接到它们的非阻塞goroutine)而没有任何OS线程.

Now, this results in 4 logical processors(and the non-blocking goroutines attached to them) without any OS threads.

因此,GO调度程序将创建4个新的OS线程,并将逻辑处理器分配给这些线程.

So, the GO scheduler creates 4 new OS threads, and assigns the logical processors to these threads.

-

从OS的角度来看,发出阻塞调用的4个OS线程显然不准占用CPU时间,因为它们没有执行任何操作.

From the OS's point of view, the 4 OS threads that made blocking calls obviously cannot be allowed to take CPU time, since they aren't doing anything.

因此它将使用其选择的其他一些非阻塞线程来切换其上下文.

So it will switch their contexts with some other non-blocking thread of its choosing.

这篇关于如果goroutine涉及用户空间线程,阻塞操作是否可以导致整个线程的上下文切换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆