10
votes

Non bloquant écrire dans le fichier C / C ++

J'écris un programme de journalisation, et j'ai besoin de lire en série une fois qu'une seconde puis d'imprimer dans un fichier journal. Le problème est que parfois, quelque chose empêche ma boucle et que les données sont sauvegardées. Après avoir chronométré toutes les activités de ma boucle, j'ai remarqué que la fonction imprime mes données au fichier journal est celle qui prend trop de temps parfois. Je cherchais dans le fichier sans blocage dans le fichier et, selon ce post:

écriture de fichier avec io chevauchée vs fichier écrit dans un fil séparé

Les "écritures sur les fichiers" ne doivent pas bloquer mon programme par défaut. Mais cela semble être.

J'utilise Mme Visual Studio Ex et j'écris une application Consol C ++. Quelqu'un peut-il me dire si fprintf et <<< / code> sont censés être non bloquants / asynchrones par défaut? Sinon, y a-t-il un moyen de les rendre?

c c++

0 commentaires

4 Réponses :


3
votes

Les flux IO sont généralement tamponnés et de chaque si souvent, ces tampons sont rougrés (au système d'exploitation, puis sur le disque), mais vous avez peu de contrôle quand et à quelle fréquence (à proprement parler, vous ne voulez pas à ...) C'est lorsque le rinçage arrive que vous voyez vos valeurs aberrantes.

"non bloquage" et "asynchrone" ne sont pas des mots que j'utiliserais avec des flux standard. Si vous souhaitez réduire ces délais, envisagez des écrivies de fichiers mappés de mémoire - Boost a une belle enveloppe portable pour des fichiers mappés en mémoire.


0 commentaires

0
votes

fprintf et << Ne pas écrire avec IO superposé par défaut, et je suis convaincu qu'il n'y a pas d'option pour l'activer. Chevauché IO ​​n'est pas portable. Vous devez utiliser WrardFile avec une structure chevauchante initialisée comme dernier paramètre.


0 commentaires

0
votes

Basé sur votre description, on dirait que vous écrivez trop peu de données trop de fois. Si l'activité IO est élevée, cela peut entraîner des retards sur les E / S de fichier tampon. Comme mentionné précédemment, vous pouvez utiliser des fichiers à base de mémoire ou utiliser des écrires de blocs. L'idée est de réduire le nombre d'écritures par Clubbing multiple écrit dans un coup, donc au lieu de faire 10 écriture de 500 octets, vous faites une ecrivage de 5k chacun. Dans la plupart des systèmes d'exploitation, la taille de la page typique (et la taille de l'écriture) est d'environ 4K (pas sûr de Windows). Alors essayez un package open source ou écrire une enveloppe qui réduira le nombre d'écritures.


0 commentaires

12
votes

Voici comment les choses fonctionnent sous Linux:

Écrit / lit à partir de fichiers réguliers ne peut pas être fait blocage de la mémoire tampon de noyau. Lorsque le noyau est sorti de la mémoire pour la mise en mémoire tampon, ils bloqueront.

de l'interface de programmation Linux: un manuel de programmation système Linux et UNIX :

Le mode anti-bloquette peut être utilisé avec des périphériques (par exemple, des terminaux et Pseudoterminaux), Tuyaux, Fifos et Sockets. (Parce que des descripteurs de fichier Pour les tuyaux et les sockets ne sont pas obtenus à l'aide d'Open (), nous devons activer Cet indicateur à l'aide de l'opération FCNTL () F_SETLFL décrite dans la section 5.3.)

o_nonblock est généralement ignoré pour des fichiers réguliers, car le cache tampon de noyau garantit que les fichiers d'E / S sur des fichiers réguliers ne bloquent pas, comme décrit à la section 13.1. Cependant, o_nonblock a un effet Pour les fichiers réguliers lorsque le verrouillage de fichier obligatoire est utilisé (section 55.4).

de programmation avancée dans l'environnement UNIX 2nd ed :

Nous avons également dit que les appels de systèmes liés aux E / S du disque ne sont pas pris en compte lent, même si la lecture ou l'écriture d'un fichier de disque peut bloquer le appelant temporairement.

de http://www.remlab.net/op/nonblock.shtml :

Les fichiers réguliers sont toujours lisibles et ils sont également toujours écrits. Ceci est clairement indiqué dans les spécifications de POSIX pertinentes. Je ne peux pas stressez cela assez. Mettre un fichier régulier dans le non-blocage a Absolument aucun effet autre que de changer un bit dans les drapeaux de fichier.

La lecture d'un fichier ordinaire peut prendre beaucoup de temps. Par exemple, s'il est situé sur un disque occupé, le planificateur d'E / S peut prendre autant Il est temps que l'utilisateur remarquera que l'application est gelée.

Néanmoins, le mode non bloquante ne fonctionnera pas. Cela ne fonctionnera tout simplement pas. Vérification d'un fichier pour la lisibilité ou la rédaction réussie toujours immédiatement. Si le système a besoin de temps pour effectuer l'opération d'E / S, il mettra la tâche dans le sommeil non interruptible de la lecture ou de l'écriture Appel système.


2 commentaires

"" régulier "écrit / lire aux fichiers réguliers ne peut pas être fait non-bloquage." - Ceci est sémantiquement correct, mais pratiquement incorrect (en supposant de votre citation TLPI selon laquelle la double négation est involontaire) . Bien que vous ne puissiez pas faire le non-blocking Syscall, dans la pratique, il ne peut jamais bloquer, sauf dans des conditions très malsaines. Les écrivies sont de simples copies sur le cache tampon, que PDFlush a finalement écrit sur le disque à sa discrétion. Sauf si la machine ne manque pas de RAM physique, le blocage ne se produira jamais. Mais lorsque cela se produit, vous serez bloqué de toute façon sur les défauts de page Haphazard.


Votre commentaire est vraiment utile. Merci mec! J'ai édité la double négation que vous avez mentionnée. J'espère que c'est corrigé.