这个问题不是关于我遇到的特定问题,而是关于我发现难以解决的问题。问题的上下文是球拍类和线程。考虑下面的actor%
类,该类包含参与者线程,在该线程的邮箱中将消息排队的方法以及接收返回值的方法(它没有任何用处,只会打印它)。
(struct message (source method values))
(define actor%
(class object%
(super-new)
(init-field
[actor-thread
(create-actor-thread this)])
(define/public (receive-message source method arguments)
(define message (message source method arguments))
(thread-send actor-thread message))
(define/public (receive-value value)
(displayln value))))
附带说明一下,如果要创建一个参与者,则他们必须首先创建一个实现该参与者理解的某些消息(作为方法)的子类。它们具有一种发送消息的机制(例如(actor-send actor 'hello 'world)
,将消息发送给使用参数actor
调用方法的actor )。hello
world
所有参与者在各自的线程中运行,该线程定义如下。简而言之:它从线程的收件箱中接收一条消息,获取源(演员),方法(符号)和一些值(列表),然后动态地将其发送给自己以调用适当的方法的实例化子类actor%
。
(define (create-actor-thread self)
(thread
(lambda ()
(let actor-loop ()
;#####----- Receive message -----#####
(define message (thread-receive))
(define source (message-source message))
(define method (message-method message))
(define values (message-values message))
(define return-value (dynamic-send self method values))
(send source receive-value return-value)
(actor-loop)))))
我知道一个事实,即被调用的消息的主体是在新线程的上下文中处理的,但是从参与者的并发角度来看,这是如何工作的呢?同时,在参与者线程进行繁重的工作时,参与者可以将消息保留在该线程的邮箱中排队。我不能四处寻找(或可以找到合理的解释)的是,actor对象似乎生活在两个上下文中:原始上下文和actor线程的上下文。两者都可以访问同一对象。是否有错误的并发感,或者是否有某种魔术使它们都能正常工作?
我无法解决(或可以找到合理的解释)的原因是actor对象似乎生活在两个上下文中:原始上下文和actor线程上下文。
actor对象本身只是驻留在堆中的一些数据。原始线程和在actor对象的初始化中创建的线程都在访问对所有线程共享的同一堆上的同一对象的引用。
在actor线程中进行方法调用时,实际上是从类方法表中获取对方法实现的引用并运行它。调用确实发生在不同的线程上下文中,但是方法实现本身也通过堆共享。
底线:这不是魔术,只是线程之间共享内存的使用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句