2017-07-17 4 views
1

J'ai le travail OCaml Async simple qui est censé écrire dans un fichier et terminer le processus.En attente de l'achèvement de Writer.write dans Caml Async

Unix.openfile "foobar" ~mode:[`Creat;`Rdwr] 
>>= fun fd -> 
let wr = Writer.create fd in 
Writer.write wr "this is a test"; 
Unix.close fd 
>>= fun() -> 
exit 0 

Cependant, il semble que fd se ferme avant l'écriture est effectuée (une partie de sexp affichée est « écrivain fd inopinément fermé »). Existe-t-il un moyen d'attendre que l'écriture soit terminée avant de fermer le descripteur de fichier? En fait, je ne comprends pas pourquoi Writer.write ne renvoie pas un Deferred.t comme le fait Reader.read. Cela ne résoudrait-il pas le problème?

Mon problème est en fait un peu plus général. Fondamentalement, j'ai un travail périodique qui écrit quelque chose dans un fichier en utilisant Clock.every'. Le programme peut quitter à tout moment et fermer les descripteurs de fichiers. Comment s'assurer que toutes les écritures sont traitées avant que le fd ne soit fermé?

Si mon travail d'arrêt est:

Unix.close fd 
>>= fun() -> 
exit 0 

Une écriture programmée peut très bien se produire entre Unix.close fd et exit 0.

Répondre

1

Dans votre cas particulier, vous ne devez pas fermer le descripteur de fichier directement avec la fonction Unix.close. L'idée est que vous avez réellement transféré la propriété de fd à l'auteur, il est donc de la responsabilité de l'auteur de fermer le descripteur de fichier. Donc, vous devez utiliser Writer.close qui renvoie une unité différée. Cette fonction, attendra jusqu'à ce que toutes les écritures en attente sont terminées, puis fermez le descripteur de fichier, par exemple,

Unix.openfile "foobar" ~mode:[`Creat;`Rdwr] 
>>= fun fd -> 
let wr = Writer.create fd in 
Writer.write wr "this is a test"; 
Writer.close fd 
>>= fun() -> 
exit 0 

répondre à votre question plus générale « Est-il possible d'attendre écriture pour terminer avant de fermer le descripteur de fichier? ". Oui, Writer.close attendra. Dans le sens qu'il reviendra un différé qui deviendra déterminé après tout est écrit et fd est fermé. Vous pouvez également utiliser un paramètre force_close, qui forcera l'opération de fermeture entraînant des écritures abruptes, si elle est considérée comme une meilleure option pour le programme suspendu. Par exemple, vous pouvez donner à un programme un délai raisonnable pour vider les données, puis terminer avec une erreur.

+0

Merci, cela répond à ma question. Cependant, qu'est-ce que cela signifie que j'ai transféré la propriété à l'écrivain? Supposons que je veuille utiliser à nouveau fd après la première écriture pour quelque chose d'autre, disons un 'lseek' pour écrire dans une partie différente du fichier. Dans ce cas, je devrais attendre la première écriture mais je ne veux pas fermer le descripteur de fichier. Y-a-t-il un moyen de faire ça? – Nemo

+1

Eh bien, votre programme sera finalement cassé, c'est la même chose qu'avec la bibliothèque de flux C, et toute autre E/S tamponnée, une fois que vous lui avez passé un descripteur, n'utilisez plus le descripteur directement, sauf si vous comprenez vraiment ce qui se passe. sous le capot. Ce n'est pas seulement un problème avec l'appel de fermeture, mais avec les écritures ordinaires, cela sortira pas dans l'ordre avec les écritures tamponnées à l'écrivain. Donc, ma suggestion est, soit ne pas utiliser l'interface 'Writer' du tout ou utiliser l'interface Writer partout. N'essayez pas de rester quelque part entre les deux. – ivg

+0

Merci, je vais essayer de comprendre cela. Je vais poser une nouvelle question si nécessaire. – Nemo