9
votes

Sécurité de la sécurité des appels de système de lecture / PRAD

J'ai peu de questions liées à lire () / préad () appels système dans un environnement multithreadé

J'utilise Mac-OSX qui est FreeBSD basé, si cela aide de quelque manière que ce soit Je n'utilise que ce fichier en mode lecture et je ne lis pas / écrire Et la langue est C / C ++

Supposons que nous ayons un fichier sur disque AAAABBBBCCCCDDDEEEEE ...

et 4 alphabets correspondent sur une page du fichier

alors Page1: AAAA

page2: BBBB ..... et ainsi de suite sur

Maintenant, j'en initie un appel de système de lecture de deux threads différents avec le même descripteur de fichier Mon intensation est de lire la première page du fil 1, deuxième page du fil 2, etc.

lire (fd, buff, taille de (page));

de la page d'homme que je suis donné pour comprendre que lire sera également incrémenter le pointeur de fichier, donc je vais certainement avoir des réponses brouillées comme

ABCC ABBB .. etc. (sans séquence particulière)

Pour remédier à ce que je peux utiliser PRADA ()

"PRADA () effectue la même fonction, mais se lit auprès de la spécification position fiée dans le fichier sans modifier le pointeur de fichier "// des pages man

Mais je ne suis pas sûr de savoir si l'utilisation de PRADA m'aidera réellement dans mon objectif, car elle ne peut pas incrémenter le pointeur de fichiers interne, il n'y a pas de garantie que les réponses ne sont pas cognées.

Toutes mes données sont alignées sur une page et je souhaite lire une page de chaque fil comme

thread 1 lit: aaaa Fil 2 Reads: BBBB Le fil 3 se lit comme suit: CCCC ... sans faire de la teneur en réalité.

J'ai aussi trouvé un message Est-il sûr de lire () à partir d'un fichier dès que Write () renvoie?

Mais ce n'était pas très utile.

Je ne suis pas sûr que je ne suis pas sûr de savoir si lire () aura le problème, que je pense que le dossier que je lis est un fichier binaire et que je suis donc limité difficile à lire et à vérifier manuellement.

Toute aide sera appréciée


0 commentaires

3 Réponses :


-1
votes

Partagez un verrou de mutex entre les deux threads, actionnez le verrou dans le fil avant de se lit et déverrouillez le verrou lorsque la lecture correcte est terminée. Voir pthread_mutex_create , pthread_mutex_lock et pthread_mutex_unlock . .


4 commentaires

C'est un remède mais il limitera les E / S à un seul fil, je ne veux pas faire cela car je ne suis intéressé que par la lecture, et pas lire-écrire


Je ne pense pas que tu le fais sans bloquer un fil sur les E / S. De plus, si vous ne bloquez que pendant la lecture simple, et non la totalité de l'exécution du fil, l'attente doit être minimale. La seule autre alternative consiste à ouvrir chaque fil d'ouvrir le fichier avec son propre descripteur de fichier, mais vous devrez savoir ce que chacun lit pour ignorer cette information. Cela ralentira également les threads comme il y aura deux fois plus d'E / S.


Ceci est inutile et non la réponse à la question de l'OP. L'ensemble du point de préad est de faire ce que veut OP, et la réponse est que oui c'est sûr.


Je n'étais pas au courant de ces fonctions. Je suppose que je n'ai jamais eu ce genre de besoin. Apprendre quelque chose de nouveau chaque jour. Le seul inconvénient, vous devez toujours être conscient de ce que le ou les autres threads traitent de sorte que vous ne doublechez pas.



10
votes

lire et écriture modifier la position du fichier ouvert sous-jacent. Ils sont "fil de fil" en ce sens que votre programme n'aura pas un comportement non défini (crash ou pire) si plusieurs threads exécutent IO sur le même fichier ouvert à la fois les utiliser, mais la commande et l'atomicité des opérations peuvent varier en fonction de la Type de fichier et la mise en œuvre.

D'autre part, préad et Pwrite Ne modifiez pas la position dans le fichier ouvert. Ils ont été ajoutés à POSIX pour exactement le but que vous souhaitez: effectuer des opérations IO sur le même fichier ouvert à partir de plusieurs threads ou processus sans les opérations interférentes avec la position des autres. Vous pouvez toujours rencontrer des problèmes avec la commande si vous mélangez préad et pwrite (ou plusieurs appels vers Pwrite ) avec des parties qui se chevauchent de la Fichier, mais aussi longtemps que vous évitez cela, ils sont parfaitement sûrs pour ce que vous voulez faire.


1 commentaires

Et ceci: pubs.opengroup.org/onlinepubs/9699919799/fonctions/... (XSH 2.9.7 Interactions de fil avec les opérations de fichier régulières).



1
votes

fcntl code> Les serrures de conseil sont des verrous sur une plage em> du fichier. Vous pouvez trouver cela utile pour sérialiser des lectures et écrit dans la même région tout en laissant la concurrence sur les régions distinctes.

int rc;
struct flock f;
f.l_type = F_RDLCK;  /* or F_WRLCK */
f.l_whence = SEEK_SET;
f.l_start = n;
f.l_len = 1;
while ((rc = fcntl(fd, F_SETLKW, &f)) == -1 && errno = EINTR)
    ;
if (rc == -1)
    perror("fcntl(F_SETLKW)");
else {
    /* do stuff */
    f.l_type = F_UNLCK;
    fcntl(fd, F_SETLK, &f);
}


2 commentaires

Soyez averti que beaucoup de verrouillage de fichiers ne fonctionnent pas entre les threads, uniquement les processus. Je ne me souviens pas de FCNTL mais ne vous en faites pas confiance. Essaye-le.


FCNTL est en fait verrouillant entre les processus. Linux.die.net/man/2/fcntl Si vous utilisez Pthread, le La bibliothèque fournit pthread_rwlock_ * Fonctions qui implémentent le verrouillage en lecture / écriture de fil. Il ne fournit pas de verrouillage de la plage cependant, vous devrez écrire votre propre ...