- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在从网络中读取数据,并且我想在获取数据时将其写入文件。写入是并发且非顺序的(想想 P2P 文件共享)。在 C 中,我会获取文件的文件描述符(在程序运行期间),然后使用 lseek
,然后是 write
,最后关闭 fd
。这些操作可以通过多线程设置中的互斥锁来保护(特别是,lseek 和 write 应该是原子的)。
我真的不知道如何在异步中获得这种行为。我最初的想法是有这样的东西。
let write fd s pos =
let posl = Int64.of_int pos in
Async_unix.Unix_syscalls.lseek fd ~mode:`Set posl
>>| fun _ ->
let wr = Writer.create t.fd in
let len = String.length s in
Writer.write wr s ~pos:0 ~len
然后,在接收到数据时异步安排写入。
我的解决方案不正确。一方面,这个 write
任务需要是原子的,但事实并非如此,因为两个 lseek
可以在第一个 Writer.write
之前执行>。即使我可以按顺序安排 write
也无济于事,因为 Writer.write
不返回 Deferred.t
。有什么想法吗?
顺便说一句,这是对先前回答 question 的跟进.
最佳答案
基本方法是拥有一个工作队列,每个工作队列执行一个原子seek/write
1 操作。不变的是一次只有一个 worker 在运行。一个更复杂的策略将采用优先级队列,其中写入由一些最大化吞吐量的标准排序,例如,写入后续位置。如果您观察到大量小写入,您也可以实现复杂的缓冲策略,然后将它们合并成更大的 block 是个好主意。
但让我们从一个简单的非优先队列开始,它通过 Async.Pipe.t
实现。对于位置写入,我们不能使用 Writer 接口(interface),因为它是为缓冲顺序写入而设计的。因此,我们将使用 Async_unix.Std
中的 Unix.lseek
和 Bigstring.really_write 函数。 really_write 是一个常规的非异步函数,因此我们需要使用
Fd.syscall_in_thread` 函数将其提升到 Async 接口(interface)中,例如,
let really_pwrite fd offset bytes =
Unix.lseek fd offset ~mode:`Set >>= fun (_ : int64) ->
Fd.syscall_in_thread fd (fun desc ->
Bigstring.really_write desc bytes)
注意:此函数将写入系统决定的字节数,但不会超过bytes
的长度。因此,您可能有兴趣实现一个将写入所有字节的 really_pwrite
函数。
整个方案将包括一个主线程,它将拥有一个文件描述符并通过 Async.Pipe 接受来自多个客户端的写入请求。假设每个写请求都是一个如下类型的消息:
type chunk = {
offset : int;
bytes : Bigstring.t;
}
那么您的主线程将如下所示:
let process_requests fd =
Async.Pipe.iter ~f:(fun {offset; bytes} ->
really_pwrite fd offset bytes)
其中 really_pwrite
是一个真正写入所有字节并处理所有错误的函数。您还可以使用 Async.Pipe.iter'
函数并在实际执行 pwrite
系统调用之前对写入进行预排序和合并。
再做一个优化说明。分配一个 bigstring 是一项相当昂贵的操作,因此您可以考虑预先分配一个 big bigstring 并从中提供小块。这将创建一个有限的资源,因此您的客户端将等待其他客户端完成写入并释放它们的 block 。因此,您将拥有一个内存占用有限的受限系统。
1)理想情况下我们应该使用 pwrite
虽然 Janestreet 只提供了 pwrite_assume_fd_is_nonblocking
函数,当调用system pwrite
已完成,实际上会阻塞整个系统。所以我们需要结合使用查找和写入。后者将释放 OCaml 运行时,以便程序的其余部分可以继续。 (此外,鉴于他们对非阻塞 fd 的定义,这个函数并没有多大意义,因为只有套接字和 FIFO 被认为是非阻塞的,据我所知,它们不支持查找操作。我将提交一个关于他们的错误跟踪器的问题。
关于asynchronous - 使用 OCaml Async 并发写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45160445/
我正在尝试以更命令的方式表达一组链式调用。例如,图像我们有一个函数,它接受一个列表和一个元素,并将该元素附加到列表的末尾: let insert l e = l @ [e] 我想一次插入几个元素。
是否有一个完整的列表(或详尽的规则)可以给 OCaml 中的自定义中缀运算符提供可能的名称? 最佳答案 如 OCaml manual 中所述, 中缀运算符必须匹配正则表达式 [-=<>@^|&+*/$
我想开始使用 OCaml 编程。由于我是 Windows 用户,我知道最好使用 Netbeans 的 OCaml 插件。 我已经从以下链接下载了上述插件:http://ocamlplugin.loki
能够做到这一点以获得最大速度不是很重要吗? 编辑: 例如,Clojure 有 map ,它使用多个核心。 Harrop 博士写道(2011 年 1 月 9 日): 语言中添加的新功能,例如一流 OCa
我在 x86 机器上用字节码编译 OCaml 程序,然后将字节码传输到 ppc64 机器。假设 ppc64 机器有 ocamlrun(为 ppc64 编译),我能在 ppc64 架构上执行我的程序吗?
我创建了一个新模块,它只是名称很长的模块的较短别名: module M = ModuleWithLongName 我处于最终可执行文件的大小很重要的情况。上面的构造是由编译器合理处理的吗(即 M 实际
我在使用 ocaml 时遇到了麻烦。 我想创建一个函数,每次调用它时都会增加我的计数器,并将我的 vargen 字符串与计数器编号连接起来,然后返回这个新字符串。 我没有成功的做法是: let (co
我正在学习 OCaml,我对变量的不变性有点困惑。根据我正在阅读的书,变量是不可变的。到目前为止一切顺利,但为什么我可以这样做: let foo = 42 let foo = 4242 我错过了什么?
非尾递归组合函数可以这样写: let rec combinations l k = if k List.length l then [] else if k = 1 then List.ma
我有一段包含camlp4引用的代码。 let f_name = "my_func" > 运行此程序后 camlp4of ,它产生这个: Ast.StExp (_loc, (Ast.ExAp
如何在 OCaml 中模拟这个 Python 习语? if __name__=="__main__": main() 见 RosettaCode其他编程语言中的示例。 最佳答案 Ocaml 中没
我开始学习 Ocaml,使用 hickey book ,我被困在练习 3.4,第 9 部分 让 x x = x + 1 在 x 2 运算结果为3 ,但我不明白为什么? 最佳答案 当你写 let x x
Rust具有线性系统。有什么(好的)方法可以在 OCaml 中模拟这个吗?例如,当使用 ocaml-lua 时,我想确保仅当 Lua 处于特定状态(堆栈顶部的表等)时才调用某些函数。 编辑 :这是最近
在 OCaml?我知道非常酷的Bitstring图书馆,但是 虽然这将是在某些协议(protocol)中解析二进制数据的好方法, 它不支持异或或移位等按位运算。 我相信该库使用的底层数据结构是 只是
我们可以像这样构造一个无限列表: let rec endless = 1::endless 我认为它会吃掉所有的内存,但是当我在 utop 中尝试时,好像不是这样。 utop显示列表已构建: val
是否可以通过合并列表的元素而不是创建列表的列表来创建列表? 例子: List.combine ["A";"B"] ["C";"D"];; 我得到: [("A", "C"); ("B", "D")] 有
我想在 OCaml 中创建一个查找表。该表将有 7000 多个条目,在查找时(通过 int)返回一个字符串。用于此任务的适当数据结构是什么?表是否应该从基本代码中外部化,如果是这样,如何“包括”查找表
我正在评估 Ocaml 顶层中的一段非常简单的代码: let p5 () = print_int 5;; p5 ();; print_string "*************************
记录和元组之间是否有任何区别而不仅仅是句法差异? 有性能差异吗? 元组和记录的实现是否相同? 您是否有可以使用元组完成但不能使用记录完成的事情的示例(和 反之)? 最佳答案 模数语法它们几乎相同。主要
OCaml 中的 ` 运算符有什么作用? let int_of_meth = function | `GET -> 0 | `POST -> 1 | `PUT ->
我是一名优秀的程序员,十分优秀!