gpt4 book ai didi

multithreading - 在Clozure Common Lisp中生成多个进程来处理许多基于套接字的连接

转载 作者:行者123 更新时间:2023-12-03 11:51:44 25 4
gpt4 key购买 nike

我有以下几点:

(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)))))

当一个连接进入时,它被接受并且流被传递到处理程序。进程在处理程序上等待(阻止)。因此,当处理程序返回时,将处理下一个连接。

解决方法是每个连接具有一个进程(/线程),因此新连接不必等待处理程序完成对较早连接的处理。

我尝试这样做:
(PROCESS-RUN-FUNCTION (gensym) 
(lambda () (funcall handler stream)))

代替 (funcall handler stream),但这最终会出错,因为在调用处理程序时流不可用。显然是因为那时with-open-stream已经退出,并且流超出了范围,因此(也许?)进行了GC。

然后我尝试了:
(loop 
(PROCESS-RUN-FUNCTION (gensym)
(lambda ()
(format t "new process ")
(handle-connection))))

而不是 (loop (handle-connection)),它以循环速度运行,从而产生了新的进程,因为等待套接字的部分不再阻塞执行。

创建单独的线程/进程以处理同一套接字上的许多连接的正确方法是什么?

最佳答案

同时关闭流时,不要使用该流。

您也不应在流程中使用变量,这些变量会从流程外部获取值。通过参数将所需的所有数据传递给作为流程运行的函数。

(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

关于multithreading - 在Clozure Common Lisp中生成多个进程来处理许多基于套接字的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41651570/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com