Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ocaml:FIFO';s读错了_Ocaml_Fifo_Mkfifo - Fatal编程技术网

Ocaml:FIFO';s读错了

Ocaml:FIFO';s读错了,ocaml,fifo,mkfifo,Ocaml,Fifo,Mkfifo,好的,我正在与FIFO合作,我试图建立一个小型库,用于未来的程序 它应该能够创建一个命名管道,读取它并在其中写入 我能够完成所有这些功能,但它不能正确读取。问题如下: 如果我说它应该读取大小为10个字符的缓冲区,则只有当我写入超过10个字符时,它才会正确打印,例如: write=“0123456789”->reads=“” write=“012345678910111213”->读取=“10111213” 我尝试了更多的代码,并对异常“with”进行了一个小的调试。 如果读取失败,则存在此异常。

好的,我正在与FIFO合作,我试图建立一个小型库,用于未来的程序

它应该能够创建一个命名管道,读取它并在其中写入

我能够完成所有这些功能,但它不能正确读取。问题如下:

如果我说它应该读取大小为10个字符的缓冲区,则只有当我写入超过10个字符时,它才会正确打印,例如:

write=“0123456789”->reads=“” write=“012345678910111213”->读取=“10111213”

我尝试了更多的代码,并对异常“with”进行了一个小的调试。 如果读取失败,则存在此异常。。。它所做的是:关闭、等待、重新启动,最后返回0(无)

然后我有一个if,只有当字符数仅大于0时才正确,否则它将打印“空”

因此,发生的情况是: write=“0123456789”->reads=“empty” write=“012345678910111213”->reads=“empty”,“10111213”

因此,在前10个字符中,他说读取失败,但他将其从FIFO中删除。为什么?

抱歉,如果有点混乱的话。代码如下:

要读取的程序:

let fifo_name = "la_fila";;

(*define the length of the buffer*)
let buflen = 2;;

let main () =
Printf.printf "Hello! Any readers? ...\n";
flush stdout;
while true do
print_string ("I've read \"" ^ bufferRead fifo_name buflen  ^ "\" from the fifo!\n");
flush stdout
done;;

(* run it *)
bufferCreate fifo_name;;
let _ = main ();;
这里是BufferLibrary:

(* Buffer Functions *)
let bufferCreate name = 
  try Unix.mkfifo name 0o664 with
    Unix.Unix_error(n,f,arg) -> Printf.printf "%s(%s) : %s\n" f arg 
      (Unix.error_message n);;

let bufferRead name size =
let frd = Unix.openfile name [Unix.O_RDONLY;Unix.O_NONBLOCK] 0o644 in
 let rec aux () =  
    let nothing = flush_all ()
    in
    let buffer = String.create size in
    let n = try (Unix.read frd buffer 0 size) with 
        Unix.Unix_error(n,f,arg) -> begin (); aux (); 0; end
    in
    if n > 0 then String.sub buffer 0 n else "empty"
 in
 aux ();; 
 (*(String.sub buffer 0 n)*)

let bufferWrite name str = 
  let length = String.length str in
  let fwr = Unix.openfile name [Unix.O_WRONLY] 0o644 in 
  Unix.write fwr str 0 length;;
编辑

open Buffers;;

let fifo_name = "la_fila";;


let main () = 
Printf.printf "CUCKOO! any consumer down there? ...\n";
flush stdout;
Printf.printf "cuckoo! Here comes a consumer! \n";

let rec reget () =
Printf.printf "-type something for it\n";
flush stdout;
let str = read_line() (*here it blocks*) in
bufferWrite fifo_name str;
reget () in
reget ();;

(* run it *)
bufferCreate fifo_name;;
main ();;
我会喜欢一些光,它杀死我


谢谢

我认为您不需要非阻塞IO,至少不需要初始测试。实际上,你希望你的读者在有人准备好写作之前阻止阅读。但是,您可能也不希望每次读取时都重新打开管道,因为这样每次都会等待写入程序。如果确实要为每次读取重新打开管道,则还应将其关闭。在我对代码的测试中,程序一直运行,直到用完所有可用的文件描述符

编辑:如果您要求非阻塞I/O,您的测试程序基本上是轮询(消耗CPU周期),等待输入显示。在开始查看任何数据之前,您将看到一些任意数量的0长度读取。这似乎就是你要报道的。如果您一直打开和关闭管道,如果某个时段没有读写器打开管道,则可能会丢失数据

对于初始测试,您真正想要做的(我很确定)是为正常(阻塞)IO打开管道一次,并在读卡器中将其永远打开(直到测试结束)。这样可以确保您看到所有数据。你可以试着改变后,工作


作为旁白,我认为许多人最终认为命名管道的语义过于挑剔。他们最终使用的是Unix域流套接字。

我忘了添加编写程序。这适用于两个单独的过程。我将把它添加到我的问题的编辑中。我不希望它被阻止,因为我希望未来的程序能够继续工作,只是偶尔阅读。。。有点补充-现在就试试我按照你的建议,尝试了一个非阻塞IO,我不再有这个问题,它读取所有内容。但是如果我要求它是非阻塞的,为什么会发生这种情况呢?同样在上一个例子中,唯一可以正常工作的场景是,如果我重新启动计算机,并且只在写入的第一个字符串处。只有这样才能正确地阅读,而下面的内容则不然。我的理论是,您正在丢失数据,因为您一直在打开和关闭管道。命名管道不是数据存储库——如果没有人读写,数据就会消失。我明白了。那么,对于不同独立进程之间的通信,您有什么建议呢。我喜欢命名管道,因为进程之间不需要依赖关系。。。最好的方式是什么?命名管道可以用于单向通信。如果这是你需要的,太好了。Unix域套接字是双向的,并且更加灵活。如果您有需要持久化的数据(在读/写文件描述符的生命周期之外),您需要将其存储在某个地方。这取决于你的问题。