本文介绍了解释有关线程的信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

"而不是只是等待它的时间片到期,一个线程可以阻止

每次它在另一个线程中启动一个耗时的活动,直到

活动结束。这比在轮询循环中旋转更好等待完成,因为如果系统必须完全依赖于时间片把它的b / b
关注到其他一些帖子。


我没有得到一个线程每次都可以阻止... " ;.

阻止是什么意思?这是否意味着如果线程B需要来自线程A的东西

线程A阻止线程B运行直到它完成但不干扰

与其他线程C?br />

谢谢,


Jon

"Instead of just waiting for its time slice to expire, a thread can block
each time it initiates a time-consuming activity in another thread until the
activity finishes. This is better than spinning in a polling loop waiting
for completion because it allows other threads to run sooner than they would
if the system had to rely solely on expiration of a time slice to turn its
attention to some other thread."

I don''t get the "a thread can block each time...". What does it mean by
blocking? Does it mean that if thread B needs something from thread A that
thread A stops thread B from running until its finished but not interfer
with some other thread C?

Thanks,

Jon

推荐答案



如果没有报价的上下文,很难确定报价中讨论的方案的详细信息

。但是...


一般来说,线程是否可以运行。如果不是,那么它将是b $ b阻止。有很多东西可以导致一个线程阻止
阻塞,但它们通常分为两类:等待一些

资源;显式等待(即调用Sleep())。


变为不可运行的线程将立即产生其当前的

时间片,允许其他一些可运行的线程启动执行。如果一个

线程不会变得不可用,要么是因为它明确地睡觉,要么是因为它使得某些函数调用需要等待一些

资源(例如,同步对象或某种i / o),它将继续执行与其时间片一样长的时间。


因此,在报价中,他们似乎在解释轮询资源

比允许操作系统阻止线程

要差得多,直到资源可用为止,因为轮询导致该线程消耗其整个时间片,而不是允许其他线程在此期间运行




假设其他线程具有相同的优先级,它们将最终得到一些时间。这只是你可以浪费很多时间

执行一个耗尽其整个时间片的线程而没有

完成任何实际的工作。如果其他

线程表现更好并且使用阻塞技术处理

资源获取,则尤其如此,因为这些线程_won''t_通常使用它们的

整个时间片。这导致一个线程'实际上并不是什么?b $ b做任何有用的事情,以获得狮子的CPU份额

时间,这恰恰相反你通常想要什么。


所以,在这个背景下,你的具体问题是:

Without the context of the quote, it''s hard to know for sure the details
of the scenario being discussed in the quote. However...

Generally speaking, a thread is runnable or not. If it is not, it will
"block". There are a variety of things that can cause a thread to
block, but they generally fall into two categories: waiting for some
resource; and waiting explicitly (i.e. calling Sleep()).

A thread that becomes unrunnable will immediately yield its current
timeslice, allowing some other runnable thread to start executing. If a
thread doesn''t become unrunnable, either because it explicitly sleeps or
because it makes some function call that involves having to wait on some
resource (for example, a synchronization object or some sort of i/o), it
will continue to execute for as long as its timeslice.

So, in the quote, they appear to be explaining that polling a resource
is much worse than allowing the operating system to block the thread
until the resource is available, because polling causes that thread to
consume its entire timeslice, rather than allowing other threads to run
during that time.

Assuming the other threads are of the same priority, they will
eventually get some time. It''s just that you can waste a lot of time
executing a thread that uses up its entire timeslice without
accomplishing any actual work. This is especially true if the other
threads are better behaved and use blocking techniques to deal with
resource acquisition, since those threads _won''t_ generally use their
entire timeslice. This results in the one thread that''s not actually
doing anything useful winding up getting the lion''s share of the CPU
time, which is exactly the opposite of what you normally would want.

So, with that background, your specific question:



线程A没有明确地停止线程B,没有。但假设线程B

使用阻塞技术等待线程A持有的资源,

线程B将被线程A隐式阻塞。而且重要的是,

线程B将无法运行,直到资源被

线程A发布。


这意味着只要线程B被阻塞,线程A和线程C

就可以在没有线程B使用任何CPU时间的情况下共享CPU。假设

你只有三个线程,那么基本上线程A和线程C

得到它们通常的CPU份额,加上它们都可以使用时间

线程B否则会使用。


例如,让我们说时间片是一秒钟。然后没有任何

阻塞并且每个线程消耗其整个时间片,在一个

三秒的时间内,每个线程将连续运行一秒。


现在,如果线程B需要线程A有的东西,它可以轮询

资源,继续每三个连续使用一秒

第二期,或者它可以阻止。如果它使用一些阻塞机制,

然后在一个三秒的时间内,线程B将使用ZERO CPU时间,

而线程的A和C将使用,平均1.5秒(但实际上,对于任何给定的三秒钟,

,其中一个线程将获得两个一个

第二个时间段,而另一个将得到一个;超过6秒

期间,两个线程将分别获得三个一秒的时间段。


当然,如果线程A也必须阻塞,然后线程C得到更多的CPU时间,因为它是唯一一个可运行的。


这显然是过于简单化了:timeslices不是在Windows上只要一秒钟就可以获得
,你从来没有只有三个线程,并且上面完全忽略了上下文切换的开销

线程。但它确实说明了基本观点。


这里的底线是民意调查很糟糕。特别糟糕。它需要

一个实际上没有工作要做的线程,并使它在系统上运行的任何线程中使用大部分CPU时间。轮询是好的b $ b几乎总是适得其反。这几乎从来都不是解决问题的正确方法。


另一方面,阻塞是解决问题的一种非常好的方法。

操作系统几乎总是有一些机制允许线程

处于不可运行状态,直到它实际需要任何资源

可用。毕竟,操作系统负责这些资源,所以它自然知道什么时候可用。因此,通过使用阻止

技术,一个无法对CPU执行任何有用工作的线程

永远不允许使用CPU,这样可以更有效地使用

的CPU和更高的净吞吐量。


与所有内容一样,一般规则也有例外。在非常具体的情况下,旋转等待可以提高性能。也就是说,如果

你知道特定资源肯定会在一段时间内变得可用

小于你的时间片,那就更好了

旋转等待它,因为如果线程阻塞它可能会有一段时间

才有机会再次运行。


一次它正在等待的资源变得可用,它仍然需要在循环线程调度中轮流等待再次获得CPU时间

。另外,当然在线程之间切换

的开销。因此,如果你需要一个特定的线程非常

响应和(这是非常重要的)你肯定知道它不会等b
等待的时间比时间片,旋转可以很好地工作。


关于这最后一点:如果线程必须等待资源的时间长于

时间片,那么旋转不会什么都不做。

线程_will_被抢先一步;没有办法阻止这一点。因此,在这种情况下旋转的所有

都浪费了CPU时间,可以由

所有其他线程使用。


旋转的线程仍然会被中断,并在循环列表的结尾处放置,以便它必须等待所有其他线程

获得机会执行。事实上,因为当其他线程保持运行时间更长时,他们可能最终能够做更多的工作

当他们最终运行时,并且因为旋转线程本身

只是浪费了一大堆时间什么都不做,最后有一个

线程旋转等待的结果往往很多_reduced_性能,即使对于

旋转线程,不要紧,整个系统吞吐量问题我上面提到了



所以,即使在这些非常具体的情况下,旋转等待可能会有所帮助,

你必须非常小心。如果你不是管理线程

调度的专家,你可以通过尝试这样的

技术轻松地使你的程序更糟糕。


Pete

Thread A doesn''t stop thread B explicitly, no. But assuming thread B
uses a blocking technique to wait on a resource being held by thread A,
thread B would be blocked by thread A implicitly. And importantly,
thread B would not be run at all until the resource was released by
thread A.

This means that as long as thread B is blocked, thread A and thread C
can share the CPU without having thread B using any CPU time. Assuming
you just have the three threads, then basically thread A and thread C
get their usual share of the CPU, plus they both get to use the time
thread B otherwise would have used.

For example, let''s say the timeslice is one second. Then without any
blocking and with each thread consuming its entire timeslice, in a
three-second period, each thread would run for one continuous second.

Now, if thread B needs something thread A has, it can either poll for
the resource, continuing to use one continuous second for each three
second period, or it can block. If it uses some blocking mechanism,
then in a single three second period, thread B will use ZERO CPU time,
while thread''s A and C will use, on average 1.5 seconds (but in reality,
for any given three second period, one of those threads will get two one
second timeslices, while the other will get one; over a six second
period, both threads will each get three one second timeslices though).

Of course, if thread A has to block as well, then thread C gets even
more CPU time, since it''s the only one runnable.

This is obviously an oversimplification: timeslices aren''t ever nearly
as long as one second on Windows, you never have only three threads, and
the above completely ignores the overhead of context switching between
threads. But it does illustrate the basic point.

The bottom line here is that polling is bad. Really bad. It takes the
one thread that actually has no work to do, and causes it to use the
most CPU time out of any thread running on the system. Polling is
almost always counter-productive. It''s almost never the right way to
solve a problem.

Blocking, on the other hand, is a very nice way to solve a problem. The
operating system almost always has some mechanism for allowing a thread
to sit in an unrunnable state until whatever resource it actually needs
is available. After all, the OS is in charge of those resources, so it
naturally knows when they become available. So by using a blocking
technique, a thread that is cannot do any useful work with the CPU is
never allowed to use the CPU, which allows for much more efficient use
of the CPU and much greater net throughput.

As with everything, there are exceptions to the general rule. In very
specific situations, a "spin wait" can improve performance. That is, if
you know that a particular resource will for sure become available
within some period of time less than your timeslice, it can be better to
spin wait for it, because if the thread blocks it could be quite a while
before it gets a chance to run again.

Once the resource it''s waiting on becomes available, it still has to
wait its turn in the round-robin thread scheduling to get CPU time
again. In addition, there is of course the overhead in switching
between threads. So if you need a particular thread to be very
responsive AND (and this is very important) you know for sure it won''t
have to wait longer than the timeslice, spinning can work well.

On this last point: if the thread will have to wait longer than the
timeslice for the resource, then spinning doesn''t do any good at all.
The thread _will_ be preempted; there is no way to prevent that. So all
that spinning in that case does is waste CPU time that could be used by
all the other threads.

The spinning thread will still get interrupted, and put at the end of
the round-robin list so that it has to wait for all the other threads to
get their chance to execute. In fact, because when other threads are
kept from running longer, they may wind up being able to do more work
when they finally do get to run, and because the spinning thread itself
just wasted a bunch of time doing nothing, the net result of having a
thread spin wait like that often is much _reduced_ performance even for
the spinning thread, never mind the issue of overall system throughput I
mentioned above.

So, even in these very specific scenarios where a spin wait may help,
you have to be very careful. If you aren''t an expert in managing thread
scheduling, you can easily make your program a lot worse by attempting a
technique like that.

Pete




更像是线程B停止运行,直到A已经提供了一些资源

可用或引发了其他类型的事件。在此期间通常没有理由坐下来和
一起旋转,所以通常B'的时间片的剩余时间将是

产生给调度程序,希望有些其他任务有一个用于CPU

资源。现在说B被阻止被阻塞。在某些事件中,并且不会重新安排
直到事件发生。如果A

是操作系统,那么这种情况就不那么奇特了,例如,每当你的任务B执行任何操作系统同步等待任何操作系统时都会发生这种情况资源,例如Console.Readline()。


HTH,

-rick-

More like thread B stops itself from running until A has made some resource
available or raised some other kind of event. There is usually no reason to sit
and spin in the meantime, so normally the remainder of B''s time slice would be
yielded to the scheduler in hopes that some other task has a use for the CPU
resource. B is now said blocked to be "blocked" on some event and will not be
rescheduled until the event occurs. It''s less exotic than it may sound - if A
is the operating system, e.g., this happens every time your task B does a
synchronous wait for any OS resource, for example Console.Readline().

HTH,
-rick-




更像是线程B停止运行直到A已经提供了一些

资源或者引发了其他类型的事件。通常

没有理由在此期间坐下来旋转,所以通常剩余的

B'的时间片将被提供给调度程序,希望有些其他

任务可用于CPU资源。 B现在被称为被阻止了

被阻止在某些事件中,并且在事件发生之前不会重新安排

。如果A是运行的b $ b系统,它就不那么具有异国情调了,例如,每当你的任务B进行同步等待时就会发生这种情况

对于任何操作系统资源,例如Console.Readline()。

More like thread B stops itself from running until A has made some
resource available or raised some other kind of event. There is usually
no reason to sit and spin in the meantime, so normally the remainder of
B''s time slice would be yielded to the scheduler in hopes that some other
task has a use for the CPU resource. B is now said blocked to be
"blocked" on some event and will not be rescheduled until the event
occurs. It''s less exotic than it may sound - if A is the operating
system, e.g., this happens every time your task B does a synchronous wait
for any OS resource, for example Console.Readline().



好​​的,但我不明白在一些事件上被阻止而且不会是

重新安排,直到事件发生。这是怎么发生的?我不能想象

如何设置这样的机器。


如果我们使用你的ReadLine()的例子那么基本上发生的是

最终这个调用可以用到硬件驱动程序。但是这个
需要一个任务切换,从用户模式转到内核模式。现在

不会让调度程序尝试并复活任务的用户模式代码

切换,因为它不知道它等待内核模式代码

完成了吗?


或者在任务开关中是否存在某些信息,比如锁或某些东西,或者b $ b告诉调度程序不要重新启动进程,而内核模式代码将会确定
那个。


因此我认为在任务切换状态下,可能会有类似

" IsBlocked"的内容。当进入内核模式时,如果它的异步可能是暂时设置IsBlocked然后释放它。如果它是同步的那么

会设置IsBlocked直到它完全结束。


我离开了吗? ;)我很难理解内部

机器如何实现这一目标。也许就像锁一样简单?


谢谢,

Jon


Ok, but I don''t understand the "blocked on some event and will not be
rescheduled until the event occurs". How does that happen? I can''t picture
how the machinery is setup to do this.

If we use your example of ReadLine() then essentially what happens is
eventually the call works its way down to a hardware driver. But this
requires a task switch somewhere to go from user mode to kernel mode. Now
wouldn''t the scheduler try and "revive" the user mode code that was tasked
switched because it wouldn''t know that its waiting for the kernel mode code
to finish?

Or is there some information in a task switch like a lock or something that
tells the scheduler not to revice a process and the kernel mode code would
determine that.

Hence I suppose in the task switch state one might have something like
"IsBlocked". When the kernel mode is entered, if its asynchronous is might
set IsBlocked momentarily but then release it. If its synchronous then it
would set IsBlocked until it is completely finished.

Am I way off? ;) Its just hard for me to understand how the internal
machinery accomplishes this. Maybe is as simple as a lock though?

Thanks,
Jon


这篇关于解释有关线程的信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 22:32