时间:2010-07-24 10:04:43

标签: multithreading concurrency process parallel-processing fiber

4 个答案:

答案 0 :(得分:56)

答案 1 :(得分:32)

我大多赞同Gian的答案,但我对一些并发原语有不同的解释。请注意,这些术语经常被不同作者使用不一致。这些是我最喜欢的定义(希望与现代共识相差不远)。

  • 过程:
    • OS管理
    • 每个都有自己的虚拟地址空间
    • 系统可以中断(抢占)以允许其他进程运行
    • 可以与不同处理器上的其他进程并行运行
    • 进程的内存开销很高(包括虚拟内存表,打开文件句柄等)
    • 进程之间创建和上下文切换的时间开销相对较高
  • 主题:
    • OS管理
    • 每个都包含"包含"在一些特定的过程中
    • 同一进程中的所有线程共享相同的虚拟地址空间
    • 可以被系统中断以允许另一个线程运行
    • 可以与不同处理器上的其他线程并行运行
    • 与线程关联的内存和时间开销小于进程,但仍然非常重要
      • (例如,通常上下文切换涉及进入内核并调用系统调度程序。)
  • 合作主题:
    • 可能是或可能不是由OS管理的
    • 每个都包含"包含"在一些特定的过程中
    • 在一些实现中,每个都包含"包含"在一些特定的OS线程中
    • 系统不能中断以允许协作对等体运行
      • (包含进程/线程当然可以中断)
    • 必须调用特殊的yield原语以允许对等协作线程运行
    • 一般不能与合作伙伴并行运行
    • 协作主题主题有很多变化,有不同的名称:
      • 纤维
      • 绿色线程
      • Protothreads
      • 用户级线程(用户级线程可以是可中断/抢占的,但这是一个相对不寻常的组合)
    • 协作线程的某些实现使用分割/分段堆栈等技术,甚至单独堆分配每个调用帧,以减少与为堆栈预先分配大块内存相关的内存开销
    • 根据实现,调用阻塞系统调用(如从网络读取或休眠)将导致整组协作线程阻塞或隐式导致调用线程产生
  • 协程:
    • 有些人使用" coroutine"和#34;合作线程"或多或少的同义词
      • 我不喜欢这种用法
    • 一些协程实现实际上是"浅"合作线索; yield只能由" coroutine输入程序"
    • 调用
    • 浅(或半协程)版本比线程更容易实现,因为每个协同程序不需要完整的堆栈(只有一个框架用于进入程序)
    • 协程框架通常具有yield原语,需要调用者明确说明哪个协同控制应转移到
  • 发电机:
    • 限制(浅)协程
    • yield只能将控制权返回给调用生成器的代码
  • 够程:
    • 合作和操作系统线程的奇怪混合
    • 无法中断(如合作线程)
    • 可以在语言运行时管理的OS线程池上并行运行
  • 事件处理程序:
    • 事件调度程序为响应某些操作而调用的过程/方法
    • 非常适合用户界面编程
    • 几乎不需要语言/系统支持;可以在库中实现
    • 一次最多可以运行一个事件处理程序;在开始下一个调度程序之前,调度程序必须等待处理程序完成(返回)
      • 使同步变得相对简单;不同的处理程序执行从不重叠
    • 使用事件处理程序实现复杂任务往往会导致反转控制流" /"堆栈翻录"
  • 任务:
    • 经理向工作人员发放的工作单位
    • 工人可以是线程,流程或机器
      • 当然,任务库使用的工作者类型对实现任务的方式有重大影响
    • 在这个不一致且容易混淆的术语列表中,"任务"拿下王冠。特别是在嵌入式系统社区,"任务"有时用来表示" process"," thread"或"事件处理程序" (通常称为"中断服务程序")。它有时也通常用于非正式地指代任何类型的计算单位。

一个让我无法通话的烦恼:我不喜欢使用短语"真正的并发" for"处理器并行性"。它很常见,但我认为这会导致很多混乱。

对于大多数应用程序,我认为基于任务的框架最适合并行化。大多数流行的(英特尔的TBB,Apple的GCD,微软的TPL和PPL)都使用线程作为工作者。我希望有一些很好的替代品使用过程,但我不知道任何。

如果您对并发感兴趣(而不是处理器并行性),事件处理程序是最安全的方法。合作线程是一个有趣的选择,但有点疯狂的西部。如果您关心软件的可靠性和健壮性,请不要使用线程进行并发。

答案 2 :(得分:0)

Protothreads只是一个切换案例实现,其作用类似于状态机,但使得软件的实现变得更加简单。它基于在case标签之前保存a和int值并返回然后返回到case之后的点的想法,通过读回该变量并使用switch来确定继续的位置。因此,protothread是状态机的顺序实现。

答案 3 :(得分:0)

在实现顺序状态机时,Protothread很棒。 Protothreads根本不是真正的线程,而是一种语法抽象,使得编写必须按顺序切换状态(从一个到另一个等等)的开关/案例状态机更加容易。

我使用了protothreads来实现异步io:http://martinschroder.se/asynchronous-io-using-protothreads/