用户级线程和内核支持的线程之间的区别? [英] Difference between user-level and kernel-supported threads?

查看:195
本文介绍了用户级线程和内核支持的线程之间的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基于该主题,我一直在浏览一些说明,尽管我对线程有一个总体的了解,但我不太确定用户级线程与内核级线程之间的差异. .

I've been looking through a few notes based on this topic, and although I have an understanding of threads in general, I'm not really to sure about the differences between user-level and kernel-level threads.

我知道进程基本上是由多个线程或单个线程组成的,但是这些线程是前面提到的两种类型吗?

I know that processes are basically made up of multiple threads or a single thread, but are these thread of the two prior mentioned types?

据我了解,内核支持的线程可以访问内核以进行系统调用和用户级线程不可用的其他用途.

From what I understand, kernel-supported threads have access to the kernel for system calls and other uses not available to user-level threads.

那么,用户级线程是否只是程序员在使用内核支持的线程来执行由于其状态而通常无法执行的操作时由程序员创建的线程?

So, are user-level threads simply threads created by the programmer when then utilise kernel-supported threads to perform operations that couldn't be normally performed due to its state?

推荐答案

这个问题有点令人困惑,所以我以两种不同的方式回答.

为清楚起见,我通常说"OS级线程"或本地线程",而不是内核级线程"(我在下面的原始答案中将其与内核线程"相混淆.)创建了OS级线程并由操作系统进行管理.大多数语言都支持它们. (C,最新的Java等),它们极难使用,因为您100%负责预防问题.在某些语言中,甚至本机数据结构(例如哈希或字典)也将在没有额外的锁定代码的情况下中断.

For clarity, I usually say "OS-level threads" or "native threads" instead of "Kernel-level threads" (which I confused with "kernel threads" in my original answer below.) OS-level threads are created and managed by the OS. Most languages have support for them. (C, recent Java, etc) They are extremely hard to use because you are 100% responsible for preventing problems. In some languages, even the native data structures (such as Hashes or Dictionaries) will break without extra locking code.

与操作系统线程相反的是由您的语言管理的绿色线程.根据语言(这些语言在C中的协程,在Go中的goroutines,在Ruby中的fibre等),这些线程被赋予了各种名称.这些线程仅存在于您的语言中,而不存在于您的操作系统中.因为该语言选择上下文切换(即在语句末尾),所以可以防止TONS产生细微的竞争条件(例如看到部分复制的结构或需要锁定大多数数据结构).程序员看到阻塞"调用(即data = file.read()),但是该语言将其转换为对OS的异步调用.然后,该语言允许 other 绿色线程在等待结果时运行.

The opposite of an OS-thread is a green thread that is managed by your language. These threads are given various names depending on the language (coroutines in C, goroutines in Go, fibers in Ruby, etc). These threads only exist inside your language and not in your OS. Because the language chooses context switches (i.e. at the end of a statement), it prevents TONS of subtle race conditions (such as seeing a partially-copied structure, or needing to lock most data structures). The programmer sees "blocking" calls (i.e. data = file.read() ), but the language translates it into async calls to the OS. The language then allows other green threads to run while waiting for the result.

绿色线程对于程序员来说要简单得多,但是它们的性能各不相同:如果您有很多线程,则绿色线程对于CPU和RAM都可能更好.另一方面,大多数绿色线程语言不能利用多核. (您甚至无法再购买单核计算机或电话!).错误的库可能会通过阻止OS调用来终止整个语言.

Green threads are much simpler for the programmer, but their performance varies: If you have a LOT of threads, green threads can be better for both CPU and RAM. On the other hand, most green thread languages can't take advantage of multiple cores. (You can't even buy a single-core computer or phone anymore!). And a bad library can halt the entire language by doing a blocking OS call.

两全其美的是每个CPU拥有一个OS线程,并且许多绿色线程被神奇地转移到OS线程上.像Go和Erlang这样的语言都可以做到这一点.

The best of both worlds is to have one OS thread per CPU, and many green threads that are magically moved around onto OS threads. Languages like Go and Erlang can do this.

用户级线程无法使用的系统调用和其他用途

system calls and other uses not available to user-level threads

这只有一半是正确的.是的,如果您自己调用操作系统,就很容易造成问题(即,执行阻塞性操作.)但是该语言通常具有替换功能,因此您甚至都不会注意到.这些替代品确实调用了内核,与您认为的略有不同.

This is only half true. Yes, you can easily cause problems if you call the OS yourself (i.e. do something that's blocking.) But the language usually has replacements, so you don't even notice. These replacements do call the kernel, just slightly differently than you think.

这是我的原始答案,但这是关于用户空间线程与仅​​内核线程的(事后看来)可能不是问题.

用户线程和内核线程完全相同. (您可以通过在/proc/中查看来发现内核线程也在那里.)

User threads and Kernel threads are exactly the same. (You can see by looking in /proc/ and see that the kernel threads are there too.)

用户线程是执行用户空间代码的线程.但是它可以随时调用内核空间.即使它以较高的安全级别执行内核代码,它仍然被认为是用户"线程.

A User thread is one that executes user-space code. But it can call into kernel space at any time. It's still considered a "User" thread, even though it's executing kernel code at elevated security levels.

内核线程是仅运行内核代码且不与用户空间进程关联的线程.这些类似于"UNIX守护程序",只是它们是仅内核的守护程序.因此,您可以说内核是一个多线程程序.例如,有一个用于交换的内核线程.这迫使所有交换问题都被序列化"到单个流中.

A Kernel thread is one that only runs kernel code and isn't associated with a user-space process. These are like "UNIX daemons", except they are kernel-only daemons. So you could say that the kernel is a multi-threaded program. For example, there is a kernel thread for swap. This forces all swap issues to get "serialized" into a single stream.

如果用户线程需要某些东西,它将调用内核,该线程将该线程标记为休眠.稍后,交换线程找到数据,因此将用户线程标记为可运行.后来,用户线程"从内核返回到用户域,好像什么也没发生.

If a user thread needs something, it will call into the kernel, which marks that thread as sleeping. Later, the swap thread finds the data, so it marks the user thread as runnable. Later still, the "user thread" returns from the kernel back to userland as if nothing happened.

事实上,所有所有线程都是在内核空间中启动的,因为clone()操作发生在内核空间中. (在您可以返回"用户空间中的新进程之前,还有许多内核核算工作要做.)

In fact, all threads start off in kernel space, because the clone() operation happens in kernel space. (And there's lots of kernel accounting to do before you can 'return' to a new process in user space.)

这篇关于用户级线程和内核支持的线程之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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