Smalltalk:单个对象是否可以通过进入无限循环来阻塞整个系统?
Smalltalk: Can a single object block the entire system by entering an infinite loop?
Since Smalltalk scheduling is non-preemptive, processes must explicitly yield or wait on a semaphore
这是否意味着进入无限循环的一个对象可能会使整个系统停止运行?
the loop can be interrupted at any time. Even an atomic loop like [true] whileTrue can be interrupted before "executing" the true object
能被什么打断?
是的,非常简单 运行
[ true ] whileTrue: [ ]
而且您将无法执行任何其他操作。
当您在 Mac 上按 comand + .
时,Pharo 有一个“拉绳”。对于 Windows 或 Linux,它是 alt 或 control。此操作应该停止你正在做的事情 运行ning 并允许你进行干预。
可能是虚拟机打断了镜像。在正常的执行流程下,VM 基本上是一个接一个地发送消息。但是,如果需要,某些事件可能会通过中断它来影响执行的自然流程。虽然具体示例可能会从一种方言变为另一种方言,但这些通常对应于 OS 需要传达给图像以供考虑的事件。
如果 VM 运行内存不足,也可能会导致中断。在这种情况下,它将中断请求它进行垃圾收集的图像。
循环很有趣,因为它们具有常规消息的语义,所以每次循环重复时都会评估循环内的代码块(#value
& friends)。因此,您应该将循环视为常规消息。但是,这种语义通常是经过优化的,因此 Smalltalk 消息不会明确请求重新评估。在这种情况下,VM 将在执行块之前检查中断。因此,如果你 运行
[true] whileTrue
在将对象true
指定为当前接收者之前(在这种情况下,没有消息)VM将检查是否有任何中断需要注意(与之前检查中断的方式相同开始执行任何给定的方法)。
大多数方言都会实现一些“中断”击键,这会产生“暂停”并打开调试器供程序员恢复手动控制。
请注意,根据方言,中断可能仅包含信号量信号。这将具有将等待进程(如果有)移动到 ProcessScheduler
的就绪队列的效果。因此,预期的“例程”可能不会立即运行,而是在下次有进程切换(在该优先级)时更改为就绪状态。
想到的最后一个例子是 Whosebug
异常(没有双关语意),其中 VM 意识到它正在 运行 退出堆栈 space 并中断通过发出异常信号来显示图像。
您还可以将 #messageNotUnderstood:
视为 VM 在意识到对象已接收到尚未实现的消息时生成的中断。在这种情况下,自然流程将发生变化,以便对象将接收消息 #messageNotUnderstood:
并将实际消息作为参数。
还有一件事。一个循环是否会拖延系统取决于进程的优先级运行ning。如果循环是 运行 低优先级,则唤醒更高优先级进程的中断将优先并 运行 当循环被发送到睡眠状态时。按照同样的逻辑,如果你的无限循环 运行s 在一个更高优先级的进程中,没有中断会阻止它。
Since Smalltalk scheduling is non-preemptive, processes must explicitly yield or wait on a semaphore
这是否意味着进入无限循环的一个对象可能会使整个系统停止运行?
the loop can be interrupted at any time. Even an atomic loop like [true] whileTrue can be interrupted before "executing" the true object
能被什么打断?
是的,非常简单 运行
[ true ] whileTrue: [ ]
而且您将无法执行任何其他操作。
当您在 Mac 上按 comand + .
时,Pharo 有一个“拉绳”。对于 Windows 或 Linux,它是 alt 或 control。此操作应该停止你正在做的事情 运行ning 并允许你进行干预。
可能是虚拟机打断了镜像。在正常的执行流程下,VM 基本上是一个接一个地发送消息。但是,如果需要,某些事件可能会通过中断它来影响执行的自然流程。虽然具体示例可能会从一种方言变为另一种方言,但这些通常对应于 OS 需要传达给图像以供考虑的事件。
如果 VM 运行内存不足,也可能会导致中断。在这种情况下,它将中断请求它进行垃圾收集的图像。
循环很有趣,因为它们具有常规消息的语义,所以每次循环重复时都会评估循环内的代码块(#value
& friends)。因此,您应该将循环视为常规消息。但是,这种语义通常是经过优化的,因此 Smalltalk 消息不会明确请求重新评估。在这种情况下,VM 将在执行块之前检查中断。因此,如果你 运行
[true] whileTrue
在将对象true
指定为当前接收者之前(在这种情况下,没有消息)VM将检查是否有任何中断需要注意(与之前检查中断的方式相同开始执行任何给定的方法)。
大多数方言都会实现一些“中断”击键,这会产生“暂停”并打开调试器供程序员恢复手动控制。
请注意,根据方言,中断可能仅包含信号量信号。这将具有将等待进程(如果有)移动到 ProcessScheduler
的就绪队列的效果。因此,预期的“例程”可能不会立即运行,而是在下次有进程切换(在该优先级)时更改为就绪状态。
想到的最后一个例子是 Whosebug
异常(没有双关语意),其中 VM 意识到它正在 运行 退出堆栈 space 并中断通过发出异常信号来显示图像。
您还可以将 #messageNotUnderstood:
视为 VM 在意识到对象已接收到尚未实现的消息时生成的中断。在这种情况下,自然流程将发生变化,以便对象将接收消息 #messageNotUnderstood:
并将实际消息作为参数。
还有一件事。一个循环是否会拖延系统取决于进程的优先级运行ning。如果循环是 运行 低优先级,则唤醒更高优先级进程的中断将优先并 运行 当循环被发送到睡眠状态时。按照同样的逻辑,如果你的无限循环 运行s 在一个更高优先级的进程中,没有中断会阻止它。