草庐IT

c# - 线程与单线程

coder 2023-07-11 原文

是否总能保证多线程应用程序比单线程应用程序运行得更快?

我有两个线程从数据源填充数据,但实体不同(例如:数据库,来自两个不同的表),应用程序的单线程版本似乎比具有两个线程的版本运行得更快。

为什么会这样?当我查看性能监视器时,两个 cpu 都非常尖?这是由于上下文切换吗?

提升 CPU 并充分利用它的最佳做法是什么?

我希望这不是模棱两可的。

最佳答案

类比可能会有所帮助。

您有一堆信件需要递送到镇上的各个地址。所以你雇了一个骑摩托车的人来送你的信。

您镇上的交通信号灯是完美的交通信号灯。除非十字路口有人,否则它们始终是绿色的。

摩托车上的那个人飞快地送来一堆信件。由于路上没有其他人,所以每盏灯都是绿色的,真棒。但是你认为嘿,这可能会更快。我知道,我会再雇一个司机。

问题是**你只有一辆摩托车*。所以现在你的第一个司机骑着摩托车转了一圈,然后不时停下来,下车,第二个司机跑上去,跳上摩托车,转了一圈。

这会更快吗? 不,当然不是。那是。添加更多线程并不能使任何事情变得更快。线程不是魔法。如果一个处理器每秒能够执行十亿次操作,那么添加另一个线程不会突然使每秒另外十亿次操作可用。相反,它从其他线程窃取 资源。如果一辆摩托车能以每小时 100 英里的速度行驶,停下自行车并让另一个司机上车并不能使它更快!显然,平均而言,在该方案中,信件的递送速度没有任何加快,它们只是以不同的顺序递送。

好吧,那如果你雇两个司机和两辆摩托车呢?现在你有两个处理器,每个处理器一个线程,这样会更快,对吧?不,因为我们忘记了红绿灯。以前,任何时候都只有一辆摩托车在高速行驶。现在有两个司机和两辆摩托车,这意味着现在有时其中一辆摩托车将不得不等待,因为另一辆在十字路口。同样,添加更多线程会减慢您的速度,因为您会花更多时间争用锁。添加的处理器越多,情况就越糟;您最终花在等红灯上的时间越来越多,而发送消息的时间越来越少。

添加更多线程可能导致负面可伸缩性,如果这样做会导致锁被争用。线程越多,争用越多,运行速度越慢。

假设您使引擎更快 - 现在您拥有更多处理器、更多线程和更快的处理器。这总是让它更快吗?不。它经常没有。提高处理器速度可以使多线程程序运行得更慢。再次,想想交通。

假设您有一个城市,有数千名司机和 64 辆摩托车,司机都在摩托车之间来回奔跑,一些摩托车在十字路口挡住了其他摩托车。现在你让所有的摩托车跑得更快。这有帮助吗?那么,在现实生活中,当您四处行驶时,您驾驶保时捷到达目的地的速度是驾驶本田思域的两倍吗?当然不是;在城市驾驶的大部分时间里,您都堵在路上

如果您可以开得更快,通常您会在交通中等待更长的时间,因为您最终会更快地驶入拥堵。 如果每个人都更快地驶向拥堵,那么拥堵会变得更糟

多线程性能可能非常违反直觉。如果你想要极高的性能,我建议不要使用多线程解决方案,除非你有一个“并行得令人尴尬”的应用程序——也就是说,一些应用程序显然可以使用多个处理器,比如计算Mandelbrot 设置或进行光线追踪或类似的事情。然后,不要在问题上投入比处理器更多的线程。但是对于许多应用程序,启动更多线程会降低速度

关于c# - 线程与单线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2902264/

有关c# - 线程与单线程的更多相关文章

  1. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  2. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  3. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  4. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  5. ruby - 如何让Ruby捕获线程中的语法错误 - 2

    我正在尝试使用ruby​​编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?

  6. ruby - 如何在 ruby​​ 中运行后台线程? - 2

    我是ruby​​的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp

  7. ruby - Rails 开发服务器、PDFKit 和多线程 - 2

    我有一个使用PDFKit呈现网页的pdf版本的Rails应用程序。我使用Thin作为开发服务器。问题是当我处于开发模式时。当我使用“bundleexecrailss”启动我的服务器并尝试呈现任何PDF时,整个过程会陷入僵局,因为当您呈现PDF时,会向服务器请求一些额外的资源,如图像和css,看起来只有一个线程.如何配置Rails开发服务器以运行多个工作线程?非常感谢。 最佳答案 我找到的最简单的解决方案是unicorn.geminstallunicorn创建一个unicorn.conf:worker_processes3然后使用它:

  8. ruby - Ruby 1.9.1 中的 native 线程,对我有什么好处? - 2

    所以,Ruby1.9.1现在是declaredstable.Rails应该与它一起工作,并且正在慢慢地将gem移植到它。它具有native线程和全局解释器锁(GIL)。自从GIL到位后,原生线程是否比1.9.1中的绿色线程有任何优势? 最佳答案 1.9中的线程是原生的,但它们被“放慢了速度”,一次只允许一个线程运行。这是因为如果线程真的并行运行,它会混淆现有代码。优点:IO现在在线程中是异步的。如果一个线程阻塞在IO上,那么另一个线程将继续执行直到IO完成。C扩展可以使用真正的线程。缺点:任何非线程安全的C扩展都可能存在使用Thre

  9. ruby - 使写入文件线程安全 - 2

    我在一个ruby​​文件中有一个函数可以像这样写入一个文件File.open("myfile",'a'){|f|f.puts("#{sometext}")}这个函数在不同的线程中被调用,使得像上面这样的文件写入不是线程安全的。有谁知道如何以最简单的方式使这个文件写入线程安全?更多信息:如果重要的话,我正在使用rspec框架。 最佳答案 您可以通过File#flock给锁File.open("myfile",'a'){|f|f.flock(File::LOCK_EX)f.puts("#{sometext}")}

  10. c# - C# 中的 Flatten Ruby 方法 - 2

    我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume

随机推荐