线程通信理论

时间:2009-02-17 02:04:13

标签: c++ c multithreading theory

线程通信背后的常见理论是什么?关于它应该如何运作,我有一些原始的想法,但有些东西不适合我。有中断的方法吗?

5 个答案:

答案 0 :(得分:11)

实际上,它与任何并发问题都是一样的:你有多个控制线程,并且不确定哪些线程执行时的哪些语句。这意味着程序中存在大量可能的执行路径,并且您的程序必须在所有路径下正确。

一般来说,可能发生故障的地方是线程之间共享状态(过去称为“轻量级进程”)。当存在共享内存区域时会发生这种情况,

为确保正确性,您需要做的是确保以不会导致错误的方式更新这些数据区域。为此,您需要确定程序的“关键部分”,其中必须保证顺序操作。那些可以是单个指令或代码行;如果语言和体系结构确保它们是 atomic ,也就是说,不能被打断,那么你就是金色的。

否则,你会把那个部分归为一类,然后把一些防护装置放在上面。经典的方法是使用信号量,这是一个原子语句,一次只允许一个控制线程过去。这些是由Edsgar Dijkstra发明的,因此有来自荷兰语的名字, P V 。当你来到 P 时,只有一个线程可以继续;所有其他线程都排队等待,直到执行线程进入关联的 V 操作。

因为这些原语有点原始,并且因为荷兰语名称不是非常直观,所以已经开发了一些更大规模的方法。

Per Brinch-Hansen发明了监视器,它基本上只是一个具有保证原子性的操作的数据结构;它们可以用信号量实现。监视器几乎就是Java synchronized语句的基础;它们使对象或代码块具有特定的行为 - 也就是说,一次只有一个线程可以“在”它们中 - 语法更简单。

还有其他模式可能。 Haskell和Erlang通过一种函数式语言来解决这个问题,这些函数语言一旦创建就永远不允许变量被修改;这意味着他们自然不需要了解同步。一些新语言,比如Clojure,有一个名为“事务性内存”的结构,这基本上意味着当一个赋值时,你可以保证赋值是原子的和可逆的。

简而言之就是这样。要真正了解它,最好查看操作系统文本,例如Andy Tannenbaum's text

答案 1 :(得分:5)

线程通信的两种最常见机制是共享状态和message passing

答案 2 :(得分:3)

线程进行通信的最常见方式是通过一些共享数据结构,通常是队列。有些线程将信息放入队列,而其他线程将其取出。队列必须受操作系统工具(如互斥锁和信号量)的保护。中断与它无关。

答案 3 :(得分:1)

要在线程之间进行通信,您需要使用操作系统和/或运行时提供的任何机制。中断可能会异常低级,但如果您的线程使用套接字或命名管道进行通信,则可能会隐式使用它们。

一种常见的模式是使用共享内存块实现共享状态,依赖于os提供的同步原语(如互斥锁)来避免在从块读取时忙于等待。请记住,如果您有线程,那么您必须已经拥有某种调度程序(无论它是来自操作系统的本机还是您的语言运行时中的模拟)。因此,这个调度程序可以提供同步对象和“休眠”功能,而不必依赖硬件支持。

套接字,管道和共享内存也在进程之间工作。有时,运行时会为您在同一进程中为线程提供更轻量级的同步方式。共享内存在单个进程中更便宜。有时你的运行时也会给你一个原子消息传递机制。

答案 4 :(得分:1)

如果你真的对线程通信的理论感兴趣,你可能需要研究像pi Calculus这样的形式主义。