1
votes

existe-t-il un document officiel qui marque la fonction de lecture / écriture comme des fonctions thread-safe?

les pages de manuel de lecture / écriture n'ont rien mentionné à propos de la sécurité des threads

D'après ce lien a >! J'ai compris que ces fonctions sont thread-safe, mais dans ce commentaire, il n'y a pas de lien vers un document officiel.

Par contre, d'après ce lien ! qui dit:

The read() function shall attempt to read nbyte bytes
from the file associated with the open file descriptor,
fildes, into the buffer pointed to by buf.
The behavior of multiple concurrent reads on the same pipe, FIFO, or 
terminal device is unspecified.

J'ai conclu que la fonction de lecture n'est pas thread-safe.

Je suis tellement confus maintenant. s'il vous plaît envoyez-moi un lien vers le document officiel sur la sécurité des threads de ces fonctions.

J'ai testé ces fonctions avec pipe mais il n'y a pas eu de problème. en testant un exemple)

merci d'avance :)


1 commentaires

Sauf indication explicite comme thread-safe, la plupart des fonctions ne le sont pas.


3 Réponses :


2
votes

Les versions thread-safe de read et write sont pread et pwrite :

pread (2)

   The pread() and pwrite() system calls are especially useful in
   multithreaded applications.  They allow multiple threads to perform
   I/O on the same file descriptor without being affected by changes to
   the file offset by other threads.


6 commentaires

oui, je sais que pread () et pwrite () sont thread-safe, mais qu'en est-il des fonctions de lecture / écriture?


Vous avez une belle réponse ici, en théorie oui: lire lui-même est thread-safe, mais cela ne signifie pas nécessairement que les choses que vous voulez en faire sont sûres pour les threads


mais dans la même référence ont été mentionnés: "le comportement n'est pas spécifié ". laquelle est correcte?


Oui, lorsque deux threads write () s en même temps, l'ordre n'est pas spécifié (quel appel d'écriture se termine en premier) donc le comportement n'est pas spécifié (sans synchronisation)


oh mon dieu :)) donc cela signifie l'ordre d'appeler les fonctions merci beaucoup.


@milad ... ouais;)



1
votes

read () et write () ne sont pas strictement thread-safe, et il n'y a pas de documentation qui dit qu'ils le sont, comme l'emplacement où les données sont lues ou écrit sur peut être modifié par un autre thread.

Par le lire la documentation (notez les parties en gras):

La fonction read () tentera de lire nbyte octets du fichier associé au descripteur de fichier ouvert, fildes , dans le tampon pointé par buf . Le comportement de plusieurs lectures simultanées sur le même tube, FIFO ou terminal n'est pas spécifié .

C'est la partie que vous avez remarquée - mais cela ne couvre pas tous les types de descripteurs de fichiers possibles, tels que les fichiers normaux. Elle s'applique uniquement aux "pipe [s], FIFO [s]" et "terminal [s]". Cette partie couvre presque tout le reste (les choses étranges comme les "fichiers" dans / proc qui sont générés à la volée par le noyau sont, bien, bizarres et très spécifiques à l'implémentation):

Sur les fichiers prenant en charge la recherche (par exemple, un fichier normal), le read () doit commencer à une position dans le fichier donnée par le décalage de fichier associé à fildes . Le décalage du fichier doit être incrémenté du nombre d'octets réellement lus.

Étant donné que le "décalage de fichier associé aux fildes " est sujet à modification à partir d'autres threads dans le processus, le code suivant n'est pas garanti de renvoyer les mêmes résultats même si exactement contenu du fichier et entrées pour fd , offset , buffer et bytes:

lseek( fd, offset, SEEK_SET );
read( fd, buffer, bytes );

Puisque read () et write () dépendent d'un état (décalage du fichier actuel) qui peut être modifié à tout moment par un autre thread, ils ne sont pas sûrs.


4 commentaires

Notez que la norme POSIX dans 2.9.7 Interactions de thread avec des opérations de fichiers régulières < / a> indique que les opérations sur les fichiers normaux (y compris read () et write () sont spécifiées comme étant des WRT atomiques l'une pour l'autre.


désolé je suis encore un peu confus. Je m'interroge juste sur la lecture et l'écriture dans des tuyaux et des FIFO [s]. Je pense que la partie en gras déclare que: la lecture à partir d'un tube n'est pas atomique. ai-je raison? ou en d'autres termes, je ne savais pas que c'était exact. "l'atomicité est indéterminée ou l'ordre d'exécution"?


@MarkBenningfield Bien que les opérations read () et write () elles-mêmes puissent être atomiques, il n'y a aucun moyen de garantir que l'offset actuel reste inchangé dans un processus multithread, il n'y a donc Vérifiez d'où proviennent les données ou où elles se retrouvent dans le fichier. Puisque read () et write () dépendent et modifient également un état qui affecte tous les threads, ils ne sont pas sûrs pour le multithread.


@milad Pour les FIFO, les tubes et les terminaux, POSIX ne spécifie simplement pas ce que fait le système et permet à différentes implémentations de spécifier leur propre comportement. POSIX exige que les opérations read () et write () sur les tubes et les FIFO jusqu'à PIPE_BUF octets soient atomiques: "Les demandes d'écriture de {PIPE_BUF } octets ou moins ne doivent pas être entrelacés avec les données d'autres processus effectuant des écritures sur le même tube. Les écritures de plus de PIPE_BUF octets peuvent avoir des données entrelacées, sur des limites arbitraires, avec des écritures par d'autres processus, que ce soit ou l'indicateur O_NONBLOCK des indicateurs d'état du fichier n'est pas défini. "



0
votes

Sur certains systèmes de fichiers embarqués, ou de très vieux systèmes de bureau qui n'ont pas été conçus pour faciliter la prise en charge du multitâche (par exemple MS-DOS 3.0), une tentative d'exécuter un fread () sur un fichier tout en un fread () est en cours d'exécution sur un autre fichier peut entraîner une corruption arbitraire du système.

Tout système d'exploitation moderne et environnement d'exécution de langage garantira qu'une telle corruption ne se produira pas à la suite d'opérations effectuées sur des fichiers non liés, ou lorsque des descripteurs de fichier indépendants sont utilisés pour accéder au même fichier de manière à ne pas le modifier. Des fonctions telles que fread () et fwrite () seront thread-safe lorsqu'elles sont utilisées de cette façon .

Le fait de lire des données à partir d'un fichier disque ne le modifie pas, mais la lecture des données de nombreux types de flux les modifiera en supprimant des données. Si deux threads exécutent tous les deux des actions qui modifient le même flux, ces actions peuvent interférer l'une avec l'autre de manière non spécifiée, même si ces modifications sont effectuées par des opérations fread () .


0 commentaires