原子地写入套接字

时间:2012-02-20 12:11:04

标签: sockets emacs lisp elisp

我正在使用process-send-string将数据发送到套接字连接,但我对此功能的效果不满意。粗略地,调用(process-send-string "foo")可能最终会发送"bar"然后发送"foo",如下所述。

正如Emacs维护者所指出的,process-send-string的C代码调用函数wait_reading_process_output(甚至在实际编写任何内容之前),这可能会运行定时器,而定时器可能会调用process-send-string ,并且在这种嵌套调用之间不执行任何排序。

这使得实际上不可能实现RPC协议,该协议旨在被不受控制的时间调用的钩子使用。所以我的问题是,我们怎样才能为此目的实现原子的“同步”写入原语?

3 个答案:

答案 0 :(得分:3)

您可以执行以下操作:

(defun my-send-cmd (proc str)
  (if (process-get proc 'my-waiting)
      (process-put proc 'my-pending (append (process-get proc 'my-pending) (list str)))
    (process-put proc 'my-waiting t)
    (process-send-string proc str)))

然后在进程过滤器中,当你得到命令的答案时,检查“my-pending”,如果是非nil,则取第一个arg,将其发送到进程,否则将my-waiting设置为nil 。 当然,这假设每个命令都会从服务器获得答案,并且您无法传输命令。

这就是说,您看到的行为应该算作一个错误,或者至少是一个错误,所以请用M-x report-emacs-bug报告。

答案 1 :(得分:2)

不是直接在钩子中使用process-send-string,而是附加到缓冲区,然后让process-send-string调用以非异步的方式运行。

答案 2 :(得分:1)

最后,对我有用的选项是使用更高级别的事务队列API(因此它无法处理各种协议),但确保交替消息的正确排序。