多线程的主要用处是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程的主要用处是啥?相关的知识,希望对你有一定的参考价值。

首先说下多线程出现的原因:

为了解决负载均衡问题,充分利用CPU资源.为了提高CPU的使用率,采用多线程的方式去同时完成几件事情而不互相干扰.为了处理大量的IO操作时或处理的情况需要花费大量的时间等等,比如:读写文件,视频图像的采集,处理,显示,保存等

多线程的好处:

1.使用线程可以把占据时间长的程序中的任务放到后台去处理

2.用户界面更加吸引人,这样比如用户点击了一个按钮去触发某件事件的处理,可以弹出一个进度条来显示处理的进度

3.程序的运行效率可能会提高

4.在一些等待的任务实现上如用户输入,文件读取和网络收发数据等,线程就比较有用了.

多线程的缺点:

1.如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换.

2.更多的线程需要更多的内存空间

3.线程中止需要考虑对程序运行的影响.

4.通常块模型数据是在多个线程间共享的,需要防止线程死锁情况的发生


CSDN博主「zhh1072773034」

参考技术A 进程中的所有线程共享进程的虚拟地址空间,进程中的线程是并行执行的,系统为每个线程划分执行时间, 参考技术B

多线程的主要用处是:

把一个进程划分为多个线程,每个线程轮流占用CPU的运算时间,操作系统不断地把线程挂起、唤醒、再挂起、再唤程,如此反复,由于现在CPU的速度比较快,给人的感觉是多个线程在同时执行,就好像有多个CPU存在于计算机中一样。

多线程的一个典型例子是:用资源管理器复制文件时,一方面在进行磁盘读写操作,同时一张纸不停地从一个文件夹飘到另一个文件夹,这个飘的动作实际上是一段视频剪辑,也就是说,资源管理器能够同时进行磁盘读写和播放视频剪辑。

扩展资料:

多线程的优点:

1、使用线程可以把占据时间长的程序中的任务放到后台去处理 。

2、用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度 。

3、程序的运行速度可能加快 。

4、在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下可以释放一些珍贵的资源如内存占用等。

5、多线程技术在ios软件开发中也有举足轻重的作用。

参考资料:百度百科-多线程

解决这个多线程问题的方法是啥?

【中文标题】解决这个多线程问题的方法是啥?【英文标题】:Which approach to take with this multithreading problem?解决这个多线程问题的方法是什么? 【发布时间】:2011-03-29 08:56:08 【问题描述】:

小问题

我想生成一个后台线程来处理提交到队列的工作项(比如一个线程池)。有些工作项能够报告进度,有些则不能。我应该使用 .NET 的无数多线程方法中的哪一种?


详细解释(避免询问half which doesn't make any sense):

我的 winforms 应用程序的主窗口垂直分成两半。左半部分包含一个带有项目的树视图。当用户双击树视图中的一个项目时,该项目在右半边打开。几乎所有对象都有很多属性,分为几个部分(由选项卡表示)。这些属性的加载需要相当长的时间,通常在 10 秒左右,有时甚至更多。而且每隔一段时间就会添加更多属性,因此时间会增加。

目前我的单线程设计使 UI 暂时无响应。这自然是不可取的。我想在后台逐部分加载东西,一旦加载一部分就可以使用。对于其他部分,我会显示一个带有加载动画或其他内容的占位符选项卡。此外,虽然某些部分是在单个冗长的整体操作中加载的,但其他部分包含许多较小的函数调用和计算,因此可以显示加载进度。对于这些部分,很高兴看到进度(特别是如果它们挂在某个地方,这种情况发生了)。

请注意,数据源不是线程安全的,所以我不能同时加载两个部分。

什么方法最适合实现这种行为?是否有一些 .NET 课程可以减轻我的工作负担,还是我应该用Thread 搞砸?

ThreadPool 进行工作项队列管理,但没有用于进度报告的设施。另一方面,BackgroundWorker 支持进度报告,但它适用于单个工作项。是否可能两者兼而有之?

【问题讨论】:

【参考方案1】:

听起来很棘手!

你说你的数据源不是线程安全的。那么,这对用户意味着什么。如果他们到处点击,但在点击其他地方之前不等待属性加载,他们可以点击需要很长时间加载的 10 个节点,然后在第 10 个节点上等待。由于数据源访问不是线程安全的,因此负载必须一个接一个地运行。这表明 ThreadPool 不是一个好的选择,因为它会并行运行负载并破坏线程安全。如果加载可以在中途中止,以防止用户在他们想要查看的页面开始加载之前必须等待最后 9 个节点加载,那将是很好的。

如果可以中止加载,我建议最好使用 BackgroundWorker。如果用户切换节点,并且 BackgroundWorker 已经很忙,请设置一个事件或其他东西来指示它应该中止现有工作,然后将新工作排队以加载当前页面。

另外,考虑一下,让在线程池中运行的线程报告进度并不是太棘手。为此,将进度对象传递给类似以下类型的 QueueUserWorkItem 调用:

class Progress

  object _lock = new Object();
  int _current;
  bool _abort;

  public int Current
  
    get  lock(_lock)  return _current;  
    set  lock(_lock)  _current = value;  
  

  public bool Abort
  
    get  lock(_lock)  return _abort;  
    set  lock(_lock)  _abort = value;  
  

线程可以写入,ui 线程可以轮询(来自 System.Windows.Forms.Timer 事件)以读取进度并更新进度条或动画。

此外,如果您包含 Abort 属性。如果用户更改节点,ui 可以设置它。 load 方法可以在其运行过程中的各个点检查中止值,如果已设置,则在不完成加载的情况下返回。

老实说,您选择哪个并不重要。所有三个选项都在后台线程上完成工作。如果我是你,我会开始使用 BackgroundWorker,因为它的设置非常简单,如果你决定需要更多东西,请考虑在之后切换到 ThreadPool 或普通 Thread。

BackgroundWorker 的另一个优点是您可以使用它的完成事件(在主 ui 线程上执行)来使用已加载的数据更新 ui。

【讨论】:

是的,如果用户点击了10个节点,他就等待。实际上,UI 允许他打开多个项目并同时查看它们,所以这是一个有效的场景。但我同意如果他关闭其中一项,加载应该中止。为他当前正在查看的项目设置优先级也是一个不错的功能,没想到这一点。所以,是的,它变得混乱。我想不会有任何远程预制的东西。顺便说一句 - 如果只有一个线程正在写入并且只有一个线程正在读取它,您不认为一个简单的 volatile int _current 就足够了吗? 是的,volatile 应该没问题。【参考方案2】:

使用线程,将您的工作放在线程安全的集合中,并在您更新 ui 以在正确的线程中执行时使用调用

【讨论】:

【参考方案3】:

.NET 4.0 通过引入Task 类型对多线程进行了很多改进,该类型表示单个可能的异步操作。

对于您的方案,我建议将每个属性(或属性组)的加载拆分为单独的任务。任务包含“父”的概念,因此每个对象的加载都可以是拥有属性加载任务的父任务。

要处理取消,请使用新的统一取消框架。为每个对象创建一个CancellationTokenSource 并将其CancellationToken 传递给父任务(将其传递给它的每个子任务)。这允许取消一个对象,这可以在当前加载的属性完成后生效(而不是等到整个对象完成)。

要处理并发(或更准确地说,-并发),请使用ParallelExtensionsExtras sample library 中的OrderedTaskScheduler。每个Task 只代表一个需要调度的工作单元,通过使用OrderedTaskScheduler,您可以确保顺序执行(在ThreadPool 线程上)。

可以通过创建 UI 更新 Task 并将其调度到 UI 线程来完成 UI 进度更新。我有一个 on my blog 的示例,我将一些更笨拙的方法包装到 ProgressReporter 辅助类型中。

Task 类型的一个优点是它以自然的方式传播异常和取消;这些通常是设计一个系统来处理像你这样的问题的更困难的部分。

【讨论】:

有趣,会去看看。

以上是关于多线程的主要用处是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程是啥意思?

多线程是什么?锁是什么?信息量是什么?以及各自的用处

多线程是啥

多线程原理是啥?

java中啥叫做线程?啥叫多线程?多线程的特点是啥

java中啥叫做线程?啥叫多线程?多线程的特点是啥?