- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想为一个简单的客户端尝试使用 Lwt_unix
模块,该客户端读取套接字中的数据,直到没有任何数据可读为止。有人告诉我 Lwt
创建非阻塞套接字,但使用我的代码,它仍然是阻塞的:
open Lwt
open Unix
(* ocamlfind ocamlc -o lwt_socket_client -package lwt,lwt.unix,unix -linkpkg -g lwt_socket_client.ml *)
let host = Unix.inet_addr_loopback
let port = 6600
let create_socket () =
let sock = Lwt_unix.socket PF_INET SOCK_STREAM 0 in
Lwt_unix.set_blocking sock false;
sock
let s_read sock maxlen =
let str = Bytes.create maxlen in
let rec _read sock acc =
Lwt.ignore_result(Lwt_io.write_line Lwt_io.stdout "_read");
Lwt_unix.read sock str 0 maxlen >>= fun recvlen ->
Lwt.ignore_result(Lwt_io.write_line Lwt_io.stdout (string_of_int recvlen));
if recvlen = 0 then Lwt.return (acc)
else _read sock (acc ^ (String.sub str 0 recvlen))
in _read sock ""
let socket_read sock =
Lwt.ignore_result(Lwt_unix.connect sock @@ ADDR_INET(host, port));
s_read sock 1024 >>= fun answer ->
Lwt_io.write_line Lwt_io.stdout answer
let () =
let sock = create_socket () in
Lwt_main.run (socket_read sock)
如果我在一个术语中尝试这个例子:
echo "totoche" | netcat -l 127.0.0.1 -p 6600
那么结果是:
./lwt_socket_client
_read
8
_read
在我按下 Ctrl+c 之前阻塞。
我都试过:
Lwt_unix.set_blocking sock false;
和
Lwt_unix.set_blocking sock true;
当然没有这条线,但它仍然是阻塞的。我做错了什么?
有关更多信息,我之前的问题之一: OCaml non-blocking client socket
最佳答案
从概念上讲,Lwt_unix.read
总是阻塞 Lwt 线程,但从不阻塞整个进程——除非进程正在等待那个 Lwt线程,并且没有其他 Lwt 线程要运行。 Lwt_unix.set_blocking
不会影响此行为。它只是更改底层套接字上的设置,因此更改 Lwt 内部使用的策略以避免阻塞进程。
因此,正如@ThomasLeonard 所提到的,执行非阻塞 read
的“惯用 Lwt”方法(从进程的角度来看)只是简单地同时运行额外的 Lwt 线程与 Lwt_unix.read
.
关于问题中的具体代码,如果底层套接字是非阻塞的,但没有数据可用——而不是成功读取零字节,这表明套接字已关闭。
Unix.read
将其转换为异常 Unix.Unix_error Unix.EAGAIN
(分别为 Unix.Unix_error Unix.EWOULDBLOCK
)。 Lwt_unix.read
在这种情况下重试 Unix.read
。因此,如果使用 Lwt_unix.read
,您不能(当前)直接响应以这种方式失败的非阻塞读取。
如果您确实想要/需要对使用 Lwt_unix
创建的套接字进行这种级别的控制,您可以这样做:
Lwt_unix.set_blocking sock false;
try
Unix.read (Lwt_unix.unix_file_descr sock) str 0 maxlen
with Unix.Unix_error (Unix.EAGAIN | Unix.EWOULDBLOCK) ->
(* Handle no data available. *)
编辑:另外,正如@ThomasLeonard 所提到的,您的代码中对 ignore_result
的一些使用可能应该是 e >>= fun () -> e'
。这会强制 Lwt 在运行 e'
之前等待 e
完成。特别是,您应该为 Lwt_unix.connect
执行此操作。
关于OCaml:Lwt 和非阻塞套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39675231/
我正在尝试使用 Lwt 编写一个终端应用程序。基本上,只要我的应用程序正在运行,我就需要使用 Lwt_io.read_line 观察终端的输入。 有没有比下面的(伪代码)更好的方法来在我的程序运行时实
有关 Ocaml Lwt 中该符号含义的任何建议: >>= 最佳答案 参见 API manual : val bind : 'a t -> ('a -> 'b t) -> 'b t bind t f
据我了解,LWT 插入始终以 SERIAL 一致性级别完成。如果为 true,这是否意味着读取作为 LWT 插入的行可以安全地以 ANY 的一致性级别读取? 换句话说,我假设 LWT 插入是完全一致的
这是一个使用 Unix 模块与子进程交互的简单程序。我只是启动一个 cat shell 命令,向它发送一个字符串并读回它: #load "unix.cma";; (* Needed if you ar
我想为一个简单的客户端尝试使用 Lwt_unix 模块,该客户端读取套接字中的数据,直到没有任何数据可读为止。有人告诉我 Lwt 创建非阻塞套接字,但使用我的代码,它仍然是阻塞的: open Lwt
我试图理解术语 lwt supported . 所以假设我有一段连接数据库并写入一些数据的代码:Db.write conn data .它还与 lwt 无关,每次写入将花费 10 sec . 现在,我
我有 6 个复制因子为 3 的节点集群。我使用普通一致性级别作为 QUORUM,串行一致性级别作为 SERIAL。 我有一个条件写入查询(IF EXIST)。如果我使用如下所示的 datastax j
我目前正在学习Lwt .我对使用异步进程用 OCaml 例程替换一些 shell 例程很感兴趣。 让我们看一下简化的第一次尝试,其中通过组合运行 cat 的两个线程来创建过滤器: let filter
我正在MirageOS(Unix)上用Ocaml开发一个Web服务,此刻我在Lwt.async()上遇到了一些麻烦。 Lwt文档指出以下内容: val async : (unit -> 'a t) -
运行 opam install cohttp不为我提供 cohttp.lwt在 findlib 中。我是否缺少使用 lwt 支持进行安装的命令行选项? 最佳答案 lwt是 cohttp 的可选依赖项.
我在通过 Godi 安装的 Ubuntu 上运行 Ocaml 3.12。 我正在浏览 Lwt tutorial .我已经启动了顶层并完成了(按照指示): # #use "topfind";; # #r
我有两个表,模型如下: CREATE TABLE IF NOT EXISTS INV ( CODE TEXT, PRODUCT_CODE TEXT, LOCATION_NUMBER TEX
(交叉发布到 lwt github 问题) 我已将我的用法归结为此代码示例,该示例将泄漏文件描述符。 假设你有: #require "lwt.unix" open Lwt.Infix let echo
可以像这样查看一个进程的所有线程的优先级和调度策略: ps H -o 'tid pri cls comm' PID 如何从命令行更改单个线程的优先级? 像renice 和chrt 这样的命令似乎影响了
我在 utop 上调用 require "lwt.simple-top";; 并尝试一个简单的示例,但它无法找到运算符 >>=。 最佳答案 #require 是一个顶层指令,它将库代码链接到顶层。它不
我正在尝试运行 LWT在我的 Mac 上并为此安装了 MAMP。我关注了these instructions ,但是当我尝试访问 http://localhost:8888/lwt/ 时,我得到: T
Cassandra 轻量级事务是否使用隐含的 SET,因此在主键方面不能有 IF 部分? 我问是因为 Datastax Cassandra Java 驱动程序(版本 2.1.5)在我准备语句时抛出 I
我正在尝试使用js_of_ocaml和node.js。如您所知,node.js 大量使用回调来实现异步请求,而无需引入显式线程。 在 OCaml 中,我们有一个非常好的线程库 Lwt,带有非常有用的语
我是一名优秀的程序员,十分优秀!