它们是什么?它们有什么用处?
我没有计算机科学学位,我的背景是VB6 -> ASP -> ASP.NET/C#。能否有人以明确简洁的方式解释一下?
它们是什么?它们有什么用处?
我没有计算机科学学位,我的背景是VB6 -> ASP -> ASP.NET/C#。能否有人以明确简洁的方式解释一下?
想象一下,如果你的程序中每一行都是一个独立的函数。每个函数接受下一行/函数要执行的参数。
使用这种模式,你可以在任何一行“暂停”执行,稍后再继续执行。你还可以做一些创意性的事情,比如暂时跳转到执行堆栈来检索值,或者保存当前执行状态到数据库中以便之后检索。
您可能比您认为的更了解它们。
异常是“仅向上”延续的一个例子。它们允许位于堆栈深处的代码调用异常处理程序以指示问题。
Python示例:
try:
broken_function()
except SomeException:
# jump to here
pass
def broken_function():
raise SomeException() # go back up the stack
# stuff that won't be evaluated
生成器是“向下”连续性的例子。它们允许代码重新进入循环,例如创建新值。
Python示例:
def sequence_generator(i=1):
while True:
yield i # "return" this value, and come back here for the next
i = i + 1
g = sequence_generator()
while True:
print g.next()
在这两种情况下,这些必须被特别地添加到语言中,而在具有continuations的语言中,程序员可以在没有这些内容的情况下创建它们。
(define (fork)
(display "forking\n")
(call-with-current-continuation
(lambda (cc)
(enqueue (lambda ()
(cc #f)))
(cc #t))))
(define (context-switch)
(display "context switching\n")
(call-with-current-continuation
(lambda (cc)
(enqueue
(lambda ()
(cc 'nothing)))
((dequeue)))))
(define (end-process)
(display "ending process\n")
(let ((proc (dequeue)))
(if (eq? proc 'queue-empty)
(display "all processes terminated\n")
(proc))))
这提供了三个函数,函数可以使用-fork、context-switch和end-process。fork操作分叉线程并在一个实例中返回#t,在另一个实例中返回#f。context-switch操作在线程之间切换,并且end-process终止线程。
以下是它们使用的示例:
(define (test-cs)
(display "entering test\n")
(cond
((fork) (cond
((fork) (display "process 1\n")
(context-switch)
(display "process 1 again\n"))
(else (display "process 2\n")
(end-process)
(display "you shouldn't see this (2)"))))
(else (cond ((fork) (display "process 3\n")
(display "process 3 again\n")
(context-switch))
(else (display "process 4\n")))))
(context-switch)
(display "ending process\n")
(end-process)
(display "process ended (should only see this once)\n"))
entering test
forking
forking
process 1
context switching
forking
process 3
process 3 again
context switching
process 2
ending process
process 1 again
context switching
process 4
context switching
context switching
ending process
ending process
ending process
ending process
ending process
ending process
all processes terminated
process ended (should only see this once)
那些在课堂上学习过分叉和线程的人通常会得到类似于这样的示例。本文的目的是演示,通过手动保存和恢复其状态 - 其续体 - 可以在单个线程中实现类似的结果。
P.S. - 我记得《On Lisp》中有类似的内容,如果你想看专业代码,可以查看该书。
return
访问的,它可以让方法从调用它的地方继续执行。另一个是通过 throw
访问的,它可以让方法在最近的匹配的 catch
处继续执行。return
或 throw
的值,并在稍后真正准备好返回或抛出时调用它们。Continuation callback = return;
callMeLater(callback);
想一下线程。一个线程可以运行,你可以得到它的计算结果。一个 continuation 是一个线程,你可以复制它,这样你就可以运行相同的计算两次。
在网络编程中,Continuations(续体)因为能很好地映射 Web 请求的暂停/恢复特性而再次受到关注。服务器可以构建一个代表用户会话的 Continuation,并在用户继续会话时恢复。