C# 我们什么时候在c中使用多线程?

C# 我们什么时候在c中使用多线程?,c#,multithreading,.net-2.0,C#,Multithreading,.net 2.0,我知道如何使用c实现多线程。但我想知道它是如何运作的 一次只运行一个线程,当该线程正在等待时,它会执行第二个线程吗? 如果第二个线程正在执行,而第一个线程已准备就绪。会发生什么? 哪个线程将被赋予优先级? 我在理解这个概念时感到困惑。我想了解我们为什么要使用多线程,以及何时使用它 提前感谢。在一个操作不需要阻止另一个操作的环境中,多线程非常有用 主要的例子是后台进程不应该锁定主用户界面线程 操作系统通常会决定谁可以在何时做什么。如果一台计算机只有一个内核,那么多线程除了上面列出的那个之外几乎没有

我知道如何使用c实现多线程。但我想知道它是如何运作的

一次只运行一个线程,当该线程正在等待时,它会执行第二个线程吗? 如果第二个线程正在执行,而第一个线程已准备就绪。会发生什么? 哪个线程将被赋予优先级? 我在理解这个概念时感到困惑。我想了解我们为什么要使用多线程,以及何时使用它


提前感谢。

在一个操作不需要阻止另一个操作的环境中,多线程非常有用

主要的例子是后台进程不应该锁定主用户界面线程

操作系统通常会决定谁可以在何时做什么。如果一台计算机只有一个内核,那么多线程除了上面列出的那个之外几乎没有什么好处。但是,随着更多内核的添加,可以同时执行更多操作


但是,即使在单核系统中,多线程也可以促进非阻塞IO,这对于提高应用程序的响应性非常重要。

线程可能会同时运行,也可能不会同时运行。在单处理器机器上,一次只运行一个线程。在多处理器系统上,多处理器、多核、超线程可以同时运行多个线程,每个处理器一个线程

操作系统确定线程何时开始运行。Windows是一个应用程序。它将运行一个线程一段时间,在Windows上称为时间片10ms或15ms,停止该线程,然后确定下一个要运行的线程,该线程可能与正在运行的线程相同。实际算法比较复杂

线程确实有优先级,所以这也会影响到这一点,在所有条件相同的情况下,高优先级线程将比低优先级线程获得更多的时间。如果不手动设置线程的优先级,那么在一个简单的情况下,它默认为正常优先级,两个线程的优先级与一个线程相同,可以运行,那么两个线程运行的时间相等,可能是循环

关于为什么要使用多线程,有两个基本原因:

速度:在多处理器系统上,由于一次可以运行多个线程,我们的代码一次可以执行多个任务。例如,如果我们正在处理一幅图像,我们将图像分割成若干部分,并在图像的每一部分上使用不同的线程。 异步操作:有些任务需要一段时间,例如,从Internet读取文件,我们希望在做其他事情时能够在后台进行,因此我们创建了一个线程,以便在进行业务时进行下载。其中一个最大的优点是在GUI应用程序中,我们不想阻止UI线程,因此用户界面仍然会响应正在发生的用户意愿处理。
如果程序中有可并行化的部分,多线程可以加快程序的执行

您可能需要查看多线程的不同资源,以了解更多信息

假设你有一个问题需要尽快解决。你有一个简单的;数到十亿。你可以做一个循环:对于var i=0;i
// execute action a concurrently across the domain to-from, where a takes the current index
void Execute(Action<int> a, int from, int to)
{
    // assert to > from, to != from, from - to > CPUs, otherwise equal ranges = CPUs
    // assert a != null
    var pllItems = Environment.ProcessorCount;
    var range = to-from;
    var ranges = new int[pllItems,2];
    var step = Convert.ToInt64(range / pllItems);

    // calculate the ranges each thread should do
    for (var i = 0; i < ranges.Length; i++) {
        var s = from+i*step; // where thread i starts
        ranges[i,0] = s; // -''-
        ranges[i,1] = s+step - 1; // where thread i ends
    }


    var ts = Thread[pllItems];
    for (var i = 0; i < pllItems; i++) ts.Start(o => {
        var currT = i; // avoid closure capture problems
        for (var x = ranges[currT, 0]; x < ranges[currT, 1], x++) {
            a(x);

            // could also have:
            // try { a(x) } catch (Exception e) { lock(ecs) ecs.Add(e); /* stop thread */ break; } 
            // return at the end of method failed threads:
            // return ecs;
        }
    });
    for (var i = 0; i < pllItems; i++) ts.Join();
}
VS2010还有一个新工具,它以图形形式显示线程如何阻塞、等待io等

在.Net/OS中有一个调度器,允许线程有不同的交错

几天前,微软发布了关于如何在.NET4中执行并行操作的文档。 具有线程的

用途

隐藏延迟,即在等待时执行其他操作 在多核的情况下利用硬件的并发性,这将提供更好的性能 区分重要性级别,即高优先级线程和低优先级线程 组织结构,即每个事件的线程、每个资源的线程、每个进程的线程
还有其他一些,但我认为这是线程的基本用法。如果您查看Windows计算机上任务管理器中的“进程”选项卡,您将看到计算机上当前处于活动状态的进程。如果将Threads列添加到视图中,您将看到每个进程中当前存在的线程数。操作系统操作系统决定如何在处理器上调度所有这些进程中的所有线程。因此,实际上,操作系统不断地确定哪些线程有工作要做,并安排这些线程在处理器上执行

现在让我们假设一台单处理器、单核机器

在本例中,您的应用程序是唯一正在执行任何操作的进程。假设您的应用程序有两个优先级相同的线程,请参见下文。在这种情况下,操作系统将在这两者之间交替 线程,安排一个线程执行,然后安排另一个线程执行,直到它们所做的工作完成。为此,操作系统将时间片授予第一个调度线程。例如,假设时间片为10毫秒,实际上比这个短得多。因此线程A将执行10毫秒。然后,操作系统将抢占线程A,以便线程B可以执行其时间片,也就是10毫秒

在两个线程完成其工作或某些事件发生之前,这种来回将不间断地继续。例如,假设线程A在线程B之前完成其工作。在本例中,线程A没有其他任务,因此操作系统将继续向线程B授予时间片,因为它是唯一有工作要做的线程。另一种可能发生的情况是线程A可以等待事件,例如,或套接字的异步读取。在发出该事件的信号或在套接字上接收到数据之前,线程A在其轨道上基本上是死的,因此操作系统将继续向线程B授予时间片,直到线程A正在等待的事件/套接字发生为止。此时,操作系统将继续在线程A和线程B之间切换以执行

这方面的一个很好的例子是目前大多数应用程序所做的背景打印。应用程序的主线程专用于处理UI事件—按钮单击、键盘按下、拖放等。如果您从最喜爱的文字处理器打印文档,从概念上讲,将打印指令发送到打印机的任务委托给了辅助线程。因此,此时,您的应用程序有两个正在运行的线程—一个线程为UI服务,另一个线程处理打印作业。因为这是在单处理器、单核机器上,所以操作系统在两个线程之间交换,为每个线程授予时间片。在这种情况下,打印作业线程将在发送完打印指令后结束,然后只剩下您的UI线程

在这一点上,您可能有一个问题:

打印这个不需要更长时间吗 在单处理器、单核机器上运行 因为操作系统必须在 打印作业线程和UI 线

答案是肯定的。这样做确实需要更长的时间。但是考虑另一种选择。如果打印作业是在UI线程上执行的,则在打印作业完成之前,用户界面将对您的输入(即单击按钮、按下键盘等)无响应。这会让您作为用户感到沮丧,因为应用程序没有响应您的输入。因此,实际上,多线程实际上是一种并行错觉,至少在单处理器、单核机器上是如此。但是,当打印作业在另一个线程上完成时,您可以与应用程序进行交互,从而获得满足感,即使打印作业以这种方式完成需要更长的时间

现在让我们转到多核机器。如果您的进程有相同的两个线程A和B要执行,那么每个线程都可以安排在单独的核心上。在这种情况下,两个线程同时运行而不中断。操作系统不必在线程之间进行交换,因为每个线程都有自己的内核来运行。有道理吗

最后,让我们考虑与线程相关的优先级再次假设单处理器,单核。默认情况下,给定应用程序中的每个线程具有相同的优先级。这意味着OS将考虑所有线程在调度方面相等。如果要执行两个线程,它们在处理器上的时间大致相同。但是,您可以通过增加/减少一个线程相对于另一个线程的优先级来调整这一点。在这种情况下,优先级较高的线程比优先级较低的线程更有利于调度,这意味着它比另一个线程获得更多的时间片。在某些有限的情况下,调整线程优先级可以提高应用程序的性能,但对于大多数应用程序来说,这并不是必需的。需要注意的是不要让线程,尤其是UI线程饿死。操作系统通过不完全饥饿线程来帮助防止这种情况。尽管如此,如果UI线程处于节食状态,那么调整优先级仍然会使应用程序显得迟钝(如果不是完全没有响应的话)

您可以阅读更多关于线程优先级和优先级的信息


我希望这会有所帮助。

那么你的意思是这两个进程将同时运行吗?在多核系统上,绝对是的。即使在单核系统上,操作系统也允许它们相当并发地运行。对于CPU空闲时的IO操作,多线程可以防止浪费。太好了。感谢您的回复。我对多线程有了更多的想法:
Parallel.For(0, Math.Pow(10,9), () => { });