首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >并发与多线程

并发与多线程
EN

Stack Overflow用户
提问于 2010-01-03 22:46:14
回答 9查看 16.4K关注 0票数 16

我对并发和多线程这样的主题不是很有经验。事实上,在我的大部分网络发展职业生涯中,我从来不需要触及这些主题。

我觉得这是一个重要的概念,特别是对于桌面应用程序,以及基本上任何其他不生成HTML :)的应用程序。

在阅读了一些关于并发性的内容之后,它似乎在Go (google编程语言)这样的语言中得到了更好的支持,我不太明白为什么一种语言在并发性这样的概念上会比其他语言更好,因为它基本上是关于能够并行地叉()进程和计算东西,对吗?这不是编程的方式吗?

多线程似乎是并发性的一个分支,因为它允许您在同一进程下并行运行事物,尽管它似乎是特定于平台的实现方式。

我想我的问题是,为什么特定语言在并发上会比其他语言更好,以及为什么fork()ing进程会是一个更好的解决方案而不仅仅是使用线程?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2010-01-03 23:06:08

首先,多个线程与多个进程是不一样的,所以fork()实际上不适用于这里。

多线程/并行处理很难。首先,您必须弄清楚如何实际划分要完成的任务。然后,您必须协调所有的并行位,这可能需要相互交谈或共享资源。然后,您需要合并结果,在某些情况下,这可能与前两个步骤一样困难。我在这里简化,但希望你能理解。

所以你的问题是,为什么有些语言会更好呢?嗯,有几件事可以让事情变得更容易:

  • 优化不变的数据结构。您希望尽可能地在并行处理中坚持不变的结构,因为它们更易于推理。有些语言对这些语言有更好的支持,还有一些语言有各种优化,即能够在不实际复制的情况下将集合拼接在一起,同时仍然强制执行不可变性。您可以像这样构建自己的结构,但是如果语言或框架为您做了这些工作,就更容易了。
  • 同步原语及其易用性。当不同的线程确实共享状态时,它们需要被同步,并且有许多不同的方法来实现这一点。同步原语数组越宽,最终任务就越容易完成。如果必须与关键部分同步,而不是读取器锁,性能就会受到影响。
  • 原子事务。甚至比一个广泛的同步原语数组更好的是根本不用使用它们。数据库引擎在这方面非常擅长;而不是你,程序员,必须弄清楚你需要锁定哪些资源,以及何时和如何锁定,你只需对编译器或解释器说,“这一行下的所有东西都需要一起发生,所以确保在我使用它的时候,没有其他人会乱搞它。”引擎会帮你找到锁的。在抽象的编程语言中,您几乎从来没有获得过这种简单性,但是您越接近,越好。将多个公共操作组合为一个的线程安全对象是一个开始。
  • 自动平行度假设您必须迭代一长串项,并以某种方式对它们进行转换,就像乘5万个10x10矩阵一样。如果您能告诉编译器:嘿,每个操作都可以独立完成,那么每个操作都使用一个单独的CPU内核,这不是很好吗?而不用自己来实现线程?有些语言支持这类东西;例如,.NET团队一直在研究PLINQ。

这些只是在并行/多线程应用程序中可以使您的生活更轻松的几个例子。我相信还有更多的。

票数 29
EN

Stack Overflow用户

发布于 2010-01-03 23:08:03

在不为并发性设计的语言中,您必须依赖低级别的系统调用,并自己管理许多事情。相反,为并发性而设计的编程语言,如Erlang,将提供隐藏低级别细节的高级构造。这使得对代码的正确性进行推理变得更加容易,同时也带来了更多的可移植代码。

此外,在为并发性设计的编程语言中,通常只有少数几种方法来执行并发的事情,这会导致一致性。相反,如果编程语言不是为并发性而设计的,那么不同的库和不同的程序员将以不同的方式进行操作,因此很难就如何实现它们做出选择。

这有点像使用自动垃圾收集的编程语言和没有垃圾收集的编程语言之间的区别。在没有自动化的情况下,程序员必须考虑很多实现细节。

多线程编程和多进程编程(即fork())的区别在于,多线程程序可能更高效,因为数据不必跨进程边界传递,但是多进程方法可能更健壮。

票数 4
EN

Stack Overflow用户

发布于 2010-01-03 23:03:40

关于为什么使用fork()而不是线程的问题:当您使用单独的进程时,您将得到地址空间的自动分离。在多线程程序中,线程使用(自然)共享内存进行通信是非常常见的。这是非常有效的,但也很难实现线程之间的所有同步,这就是为什么有些语言比其他语言更擅长多线程:它们提供更好的抽象来处理线程间通信的常见情况。

使用单独的进程,您不会在相同程度上遇到这些问题。通常,您在进程之间设置通信以遵循某种形式的消息传递模式,这更容易得到正确的处理。(您也可以在进程之间使用共享内存,但这并不像消息传递那样常见。)在Unix系统上,fork()通常非常便宜,因此传统的Unix并发程序设计使用进程和管道在它们之间进行通信,但是在进程创建是一种昂贵操作的系统上,线程通常被认为是更好的方法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1996648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档