You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pharo 10.0多进程Singleton模式实现:如何通过测试?

Pharo 10.0(Smalltalk)多进程单例模式实现问题

我在Pharo 10.0(Smalltalk)中实现多进程环境下的Singleton(单例)模式,但无法通过以下测试用例。先后尝试两种实现方式均失败,寻求解决方案。

测试代码

"SingletonTest"
testCurrent
        
    | semaphore object1 object2 |
    Singleton initialize.

    semaphore := Semaphore new.

    [ 
    Processor yield.
    object1 := Singleton current.
    semaphore signal ] fork.

    object2 := Singleton current.

    semaphore wait.
    self assert: object1 identicalTo: object2

第一种失败实现

"Singleton class"
current

    Transcript
        show: 'start';
        cr. 
    current := current ifNil: [ 
                   Transcript
                       show: 'creating..';
                       cr.
                   self new ].
    ^ current

initialize

    isProcessing := false.
    current := nil

第二种失败实现

"Singleton class"
current

    [ isProcessing ] whileTrue: [  ].
    isProcessing := true.
    current := current ifNil: [ 
                   (Delay forSeconds: 2) wait.
                   self new ].
    isProcessing := false.
    ^ current

initialize

    isProcessing := false.
    current := nil

问题分析与解决方案

失败原因

  1. 第一种实现:current := current ifNil: [...]并非原子操作。多进程竞争时,第一个进程还在执行self new创建实例的过程中,第二个进程检查current仍为nil,会进入分支创建新实例,导致最终生成多个不同的单例对象。
  2. 第二种实现:忙等待[isProcessing] whileTrue: []与后续设置isProcessing := true的操作不是原子的。两个进程可能同时检测到isProcessing为false,进而都进入创建分支,同样会生成多个实例。

正确实现

利用Smalltalk的Semaphore实现互斥临界区,保证current的检查与创建操作是原子执行的:

"Singleton class"
current
    | instance |
    semaphore ifNil: [ semaphore := Semaphore forMutualExclusion ].
    semaphore critical: [
        instance := current ifNil: [ self new ].
        current := instance
    ].
    ^ instance

initialize
    semaphore := nil.
    current := nil

说明

  • Semaphore forMutualExclusion创建一个互斥信号量,确保同一时间只有一个进程能进入critical:代码块。
  • 临界区内的代码原子执行,避免了多进程同时检查current是否为nil的竞争问题,保证只会创建唯一的单例实例。

内容的提问来源于stack exchange,提问作者Yuji Hamaguchi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 19:32:59