在 Clozure Common Lisp 中产生多个进程来处理许多基于套接字的连接
Spawning multiple processes to handle many socket based connections in Clozure Common Lisp
我有以下内容:
(defun serve (&key (port 80) (handler #'IDENTITY))
(WITH-OPEN-SOCKET
(socket :LOCAL-PORT port
:LOCAL-HOST "localhost"
:CONNECT :PASSIVE
:REUSE-ADDRESS t)
(flet ((handle-connection ()
(with-open-stream
(stream (ACCEPT-CONNECTION socket :wait t))
(funcall handler stream))))
(loop (handle-connection)))))
当一个连接进来时,它被接受并且一个流被传递给处理程序。进程在处理程序上等待(阻塞)。所以下一个连接在handler returns.
时被处理
解决方法是每个连接有一个进程(/线程),因此新连接不必等待处理程序完成对较早连接的处理。
我尝试这样做:
(PROCESS-RUN-FUNCTION (gensym)
(lambda () (funcall handler stream)))
而不是 (funcall handler stream)
,但这最终会出错,因为在调用处理程序时流不可用。很明显,因为那时 with-open-stream 已经退出,并且流超出了范围,因此(也许?)GC'd。
然后我尝试了:
(loop
(PROCESS-RUN-FUNCTION (gensym)
(lambda ()
(format t "new process ")
(handle-connection))))
而不仅仅是 (loop (handle-connection))
,它会以循环的速度运行产生新进程,因为等待套接字部分不会再阻止执行。
创建单独的 threads/processes 以处理同一套接字上的多个连接的正确方法是什么?
您不应在关闭流的同时使用流。
您也不应在流程中使用变量,这些变量会从流程外部获取值。通过参数将您需要的所有数据传递给函数,运行 作为一个进程。
(let ((accepted-stream (acception-connection socket ; just take the stream
:wait t)))
(process-run-function ; run a function as a process/thread
(gensym "CONNECTION-HANDLER-") ; generate a name
(lambda (stream) ; take the one argument, the stream
(unwind-protect (progn ...) ; do something, with clean-up
(close stream))) ; make sure the stream gets closed
accepted-stream)) ; pass the stream, which then gets passed to
; the lambda function
我有以下内容:
(defun serve (&key (port 80) (handler #'IDENTITY))
(WITH-OPEN-SOCKET
(socket :LOCAL-PORT port
:LOCAL-HOST "localhost"
:CONNECT :PASSIVE
:REUSE-ADDRESS t)
(flet ((handle-connection ()
(with-open-stream
(stream (ACCEPT-CONNECTION socket :wait t))
(funcall handler stream))))
(loop (handle-connection)))))
当一个连接进来时,它被接受并且一个流被传递给处理程序。进程在处理程序上等待(阻塞)。所以下一个连接在handler returns.
时被处理解决方法是每个连接有一个进程(/线程),因此新连接不必等待处理程序完成对较早连接的处理。
我尝试这样做:
(PROCESS-RUN-FUNCTION (gensym)
(lambda () (funcall handler stream)))
而不是 (funcall handler stream)
,但这最终会出错,因为在调用处理程序时流不可用。很明显,因为那时 with-open-stream 已经退出,并且流超出了范围,因此(也许?)GC'd。
然后我尝试了:
(loop
(PROCESS-RUN-FUNCTION (gensym)
(lambda ()
(format t "new process ")
(handle-connection))))
而不仅仅是 (loop (handle-connection))
,它会以循环的速度运行产生新进程,因为等待套接字部分不会再阻止执行。
创建单独的 threads/processes 以处理同一套接字上的多个连接的正确方法是什么?
您不应在关闭流的同时使用流。
您也不应在流程中使用变量,这些变量会从流程外部获取值。通过参数将您需要的所有数据传递给函数,运行 作为一个进程。
(let ((accepted-stream (acception-connection socket ; just take the stream
:wait t)))
(process-run-function ; run a function as a process/thread
(gensym "CONNECTION-HANDLER-") ; generate a name
(lambda (stream) ; take the one argument, the stream
(unwind-protect (progn ...) ; do something, with clean-up
(close stream))) ; make sure the stream gets closed
accepted-stream)) ; pass the stream, which then gets passed to
; the lambda function