独家代理

Scoop with agents

我正在尝试同时使用代理回调。不幸的是,无论我做什么,它似乎总是 运行 顺序而不是并行。 (没有代理它没有)

主要 class(应用程序):

class
    APPLICATION

inherit
    ARGUMENTS

create
    make

feature {NONE} -- Initialization

    make
            -- Run application.
        local
            a1 : separate PROCEDURE
            a2 : separate PROCEDURE
        do
            create my_counter.make (1, 100_000_000)
            create my_counter2.make (2, 100_000_000)

            launch_counter(my_counter)
            launch_counter(my_counter2)

        end

feature -- Launch

    launch_counter(c: separate COUNTER)
        do
            c.run (5, agent print_hello)
        end

    print_hello
        do
            print("Hello!%N")
        end

feature -- Access

    my_counter : separate COUNTER
    my_counter2 : separate COUNTER

end

计数器 class:

class
    COUNTER

inherit
    EXECUTION_ENVIRONMENT


create
    make

feature -- Initilzation
    make (i: INTEGER; delay: INTEGER)
        do
            id := i
            delay_time := delay
        end

feature -- Stuff

    run (times: INTEGER; p: separate PROCEDURE)
    local
        c : INTEGER
    do
        from
            c := times
        until
            c = 0
        loop
            print("COUNTER: " + id.out)
            p.call
            sleep(delay_time)
            c := c - 1

        end

    end

feature {NONE} -- Access

    delay_time : INTEGER
    id: INTEGER

end

预期输出:

COUNTER: 1Hello!
COUNTER: 2Hello!
COUNTER: 1Hello!
etc.

实际输出:

COUNTER: 1Hello!
COUNTER: 1Hello!
COUNTER: 1Hello!
COUNTER: 1Hello!
COUNTER: 1Hello!
COUNTER: 2Hello!
COUNTER: 2Hello!
COUNTER: 2Hello!
COUNTER: 2Hello!
COUNTER: 2Hello!

我需要更改什么才能使 运行 符合预期?

代理对象保持对目标的引用,在您的示例中是 APPLICAITON 类型的根对象,因此对 print_hello 的所有调用都会同步。为避免这种情况,调用代理的对象应记录在 COUNTER 对象中并从那里使用。

这可以通过将属性 action 添加到 class COUNTER 并更新其创建过程来实现

make (i: INTEGER; delay: INTEGER; a: separate PROCEDURE)
    do
        id := i
        delay_time := delay
        action := a
    end
...
action: separate PROCEDURE

然后将使用以下代码代替 COUNTER.run 中的 p.call(特征 run 不再有参数 p):

        separate action as p do
            p.call
        end

现在 p 未锁定功能 run 的入口,因此回调可以由不同的处理器交替执行。