Smalltalk:单个对象是否可以通过进入无限循环来阻塞整个系统?
由于 Smalltalk 调度是非抢占式的,进程必须显式地让步或等待信号量
这是否意味着进入无限循环的一个对象可能会使整个系统停顿?
循环可以随时中断。即使像 [true] whileTrue 这样的原子循环也可以在“执行”真正的对象之前被中断
它可以被什么打断?
回答
可能会中断映像的是虚拟机。在正常的执行流程下,VM 基本上是一个接一个地发送消息。但是,如果需要,某些事件可能会通过中断它来影响执行的自然流程。虽然具体示例可能会从一种方言更改为另一种方言,但这些通常对应于需要传达给图像以供考虑的 OS 事件。
如果 VM 内存不足,也可能会导致中断。在这种情况下,它将中断请求它进行垃圾收集的图像。
循环很有趣,因为它们具有常规消息的语义,因此#value每次循环重复时都会评估循环内的代码块(& 朋友)。因此,您应该将循环视为常规消息。然而,这个语义通常被优化,所以重新评估不是由 Smalltalk 消息显式请求的。在这种情况下,VM 将在执行块之前检查中断。因此,如果你运行
[true] whileTrue
在将对象指定true为当前接收者(在这种情况下,没有消息)之前,VM 将检查是否有任何需要注意的中断(与它在开始执行任何给定方法之前检查中断的方式相同)。
大多数方言实现了一些“中断”键击,这会产生“暂停”并为程序员打开调试器以恢复手动控制。
请注意,根据方言,中断可能仅由信号量的信令组成。这将具有将等待进程(如果有)移动到ProcessScheduler. 因此,预期的“例程”可能不会立即运行,而是在下一次有进程切换(在该优先级级别)时更改为就绪状态。
想到的最后一个例子是StackOverflow异常(没有双关语),其中 VM 意识到它的堆栈空间不足,并通过发出异常信号来中断图像。
您也可以将#messageNotUnderstood:视为虚拟机在意识到对象收到了没有实现的消息时产生的中断。在这种情况下,自然流将发生变化,以便对象将接收#messageNotUnderstood:以实际消息作为参数的消息。
还有一件事。循环是否会停止系统取决于它正在运行的进程的优先级。如果循环以低优先级运行,唤醒更高优先级进程的中断将优先并在循环进入睡眠状态时运行。按照相同的逻辑,如果您的无限循环在更高优先级的进程中运行,则中断不会阻止它。
- Yes. But you can have processes running at even higher priorities, which won't get interrupted. Of course, it is up to the programmer to carefully decide which processes must run at those priorities and usually, unless you are a system programmer, you will give your processes lower priorities.