2013-05-20 106 views
1

线程被视为轻量级进程。他们实际上运行的速度是否会比分叉进程数量相等?哪个更快perl,Parallel :: ForkManager或线程?

+1

尝试和衡量... –

+3

不成熟的优化是所有邪恶的根源。编写符合问题域的程序。你甚至可能没有线程与进程的瓶颈。 – Jens

+0

你的代码运行速度太慢了吗?如果没有,那么没有什么可以解决的。如果是这样的话,除了多处理机制之外还有很多地方可以看。 – Borodin

回答

4

线程被视为轻量级进程。

哦不,他们不是。 Perl线程模型与Windows系统上的fork嘲讽交织在一起。在许多方面,在Perl中产生一个新线程的行为与分离新进程的行为相同:两个结果控制流在之间运行,单独的perl口译为。也就是说,整个程序状态是复制来做一个新的解释器。

它们实际上运行的速度是否比相同数量的分叉进程快?

不太可能。产生一个新的线程是软件方面的,并由perl完成。分叉是由操作系统(在* nix系统上)完成的,它可以利用写入时复制技术。这可以使分叉更便宜。一个小测试:

$ time perl -Mthreads -e'threads->new(sub{threads->exit})->detach for 1 .. 5E3' 
real 0m10.651s 
user 0m16.421s 
sys  0m1.904s 
$ time perl -Mthreads -e'fork || exit for 1 .. 5E3' 
real 0m2.347s 
user 0m0.032s 
sys  0m0.516s 

这产生了五千个线程/进程。当它在Linux上进行测试时,产生一个新进程变得更快。其他操作系统可能不是这种情况。

这并不是说Perl线程将毫无用处:它们提供了许多好处,例如可选的共享数据,传递数据的队列,管理共享资源的信号量,线程可以返回的值等等。共享数据的最简单方法进程间(不使用模块)是内置的pipe,它创建两个链接的文件句柄。


不要混淆字线程其彼此不同的解释:

  • 内核线程是硬件级别的执行线。他们不是普遍安排,而是平行运行。每个处理器至少有一个线程。

  • 操作系统线程由操作系统提供。现代操作系统自己调度线程执行(抢先调度)。通常,所有数据都是共享的,线程只有不同的堆栈。 Perl线程选择不强调共享属性。

  • 软件线程,也绿色线程由软件本身调度,通常通过协作调度。许多具有廉价线程的语言选择此模型,例如走。两条绿线不一定平行运行。协程和绿线实际上是相关的概念:都描述了并发的执行路径。

    软件线程有时可能比操作系统线程运行得更快,因为软件可以在程序中方便的地方使上下文切换。(操作系统线程或进程之间的抢先式切换更为昂贵,因为操作系统内核必须定期运行,并且处理器高速缓存和寄存器将不得不使用每个上下文切换中的另一个线程的数据进行更新。编写常规应用程序代码)

    Perl线程通常不使用此模型,但存在用于协程的模块(Coro)。

+0

“哦,不,它们不是,Perl线程模型与Windows系统上的叉子模拟相互交织。”并非如此。 'fork'在Windows上使用线程,而不是相反。 – ikegami

+0

你的基准是荒谬的毫无价值。你的结论是分叉更快无法从中得出结论。 1)这是一个非常糟糕的线程模型,所以你没有测试线程,你正在线程错误的代码。 2)叉子除了前期成本之外还有很多成本。 – ikegami

+0

@ikegami IIRC,通过线程实现对Windows上'fork'内建的支持。是不是perl中的代码部分重用于线程支持,因此将fork类语义带入Perl线程模型?是的,该基准并不考虑线程模块暗示的间接性。但我不明白它是如何不显示*开始*在我的特定perl/OS/PC组合上,并行计算通过'fork'更便宜。 – amon

2

threadsforks模块提供相同的接口。您可以通过更改程序中的单个词来在工作线程和工作进程之间切换。自己测试一下。

这种差异将会被你如何使用线程/分支所黯然失色。误食它们会极大地减慢你的程序。

+0

我不打算在并行进程(或线程)之间共享任何数据。这条信息会改变什么? –

+0

让我想知道你为什么要用。 – ikegami

相关问题