relis ce qu'a dit.. soit le PO soit valefor...
Lire un fichier alors que l'écriture n'est pas faite PHYSIQUEMENT.... donc rien à voir avec rsync, fflush, etc..
Version imprimable
relis ce qu'a dit.. soit le PO soit valefor...
Lire un fichier alors que l'écriture n'est pas faite PHYSIQUEMENT.... donc rien à voir avec rsync, fflush, etc..
Et pourquoi est-ce illogique ?
Tu es un OS. Un processus te demande de lire. Tu as les données dans le cache. Pourquoi attendre d'avoir fini de les reporter "PHYSIQUEMENT" sur le prériphérique de stockage (sachant qu'il peut lui aussi posséder un cache) alors que tu les as à portée de main, et que tu sais qu'elles sont à jour parce que ce disque-là t'appartient exclusivement ?
Naturellement, ça peut se compliquer pour des supports mutualisés : Dans ce cas-là, un cache pourrait s'avérer invalide sans un bon système de synchronisation/verrouillage....
Ouai et en relisant le man de write (truc que je n'ai jamais plus du refaire depuis la première fois où j'ai utilisé la fonction ;)), j'ai vu qu'il y avait un flag O_SYNC pour ne pas rendre la main tant que ce n'était pas écrit.
Concernant le "cache" avec l'expérience des clés usb, on s'en aperçoit bien sous Linux aussi. Quand on démonte la clef, cela prend du temps (souvent proportionnel à la quantité de mémoire de la station).
Il y a deux niveaux de "caches" : ceux du fs et les buffers du driver (8k en général sous Linux). Je vais essayer d'en apprendre un peu plus sur le fonctionnement de ces différents niveaux, et si quelqu'un a un bon article explicatif je suis preneur.
Des caches sont geres. Et les lectures se font a partir de ceux-ci. Si je te comprends bien, ce programme devrait afficher des temps similaire que fsync soit appele ou pas. Et des temps non similaire suivant le systeme de fichier...Citation:
Envoyé par souviron34
C'est loin d'etre le cas.
Il y a peu de variation sans fsync suivant le systeme de fichier (1 disque lent, 1 disque rapide, 1 systeme de fichier en memoire) -- le temps etant a chaque fois inferieur au temps d'acces des disque. Et fsync prend du temps.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 #include <fcntl.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char** argv) { int status = EXIT_FAILURE; char const *file_name = "/tmp/souviron"; int wfd, rfd; char buffer[4] = "toto"; double total_time; struct timeval start_time; struct timeval end_time; if (argc > 1) { file_name = argv[1]; } wfd = open(file_name, O_RDWR|O_CREAT|O_TRUNC, 0666); if (wfd == -1) { perror("Unable to open temporary file for writing"); return EXIT_FAILURE; } rfd = open(file_name, O_RDONLY); if (rfd == -1) { perror("Unable to open temporary file for reading"); goto close_write; } if (gettimeofday(&start_time, 0)) { perror("getting start time"); goto close_read; } if (write(wfd, buffer, sizeof buffer) != sizeof buffer) { perror("Error while writing"); goto close_read; } if (read(rfd, buffer, sizeof buffer) != sizeof buffer) { perror("Error while reading"); goto close_read; } #ifdef FSYNC if (fsync(wfd) == -1) { perror("Error while syncing file"); goto close_read; } #endif if (gettimeofday(&end_time, 0)) { perror("getting end time"); goto close_read; } total_time = end_time.tv_usec-start_time.tv_usec; if (total_time < 0) { total_time += 1000000; start_time.tv_sec += 1; } total_time /= 1000000; total_time += end_time.tv_sec-start_time.tv_sec; printf("Time needed: %.6f s\n", total_time); if (strcmp(buffer, "toto") != 0) { puts("Same data read"); } else { puts("Other data read"); } status = EXIT_SUCCESS; close_read: close(rfd); close_write: close(wfd); remove(file_name); return status; }
En passant, je suis surpris que le second open() marche: J'aurais pensé que le premier open() avait pris l'accès exclusif au fichier...
D'un autre côté, il est possible que l'accès exclusif soit pour le processus et non pour le descripteur...
Il n'y a pas d'acces exclusif automatique sous Unix. Deux systemes:Citation:
Envoyé par Médinoc
- un qui necessite que chaque process teste lui meme et qui permet de gerer des regions independamment.
- sur certain systeme de fichier, il y a un flag qu'on peut mettre empechant un acces en ecriture simultanement a n'importe quel autre acces. Mais il faut que le fichier existe.
Citation:
Envoyé par Médinoc
Primo JE NE SUIS PAS UN OS. .. Je suis un programme utilisateur... qui utilise (en parallèle à 500 autres) une fonction d"une bibliothèque qui est "écrit_chunk"..
Donc je ne DOIS PAS faire d'à priori sur comment se passe physiquement une écriture..... Je dois être sûr que cela se passera correctement, quels que soient les paramètres de configuration (et en admettant que je sache ce qu'est un driver (ce qui ne devrait pas être le cas) je ne PEUX PAS dépendre de la configuration de tel ou tel driver...).
il y a les LOCK..Citation:
Envoyé par Jean-Marc.Bourguet
Mais aussi pour répondre...
Admettons que tu aies 25 programmes écrivant dans 50 fichiers simultanéments.
Admettons qu'un programme fasse ce que tu dis : ouvre un fichier, envoie 5 Megs à écrire, ouvre ce MEME fichier en lecture, veuille lire la taille...
Je REPETE que c'est de la MAUVAISE PROGRAMMATION (et là on ne parle pas système, ou OS), mais UTILISATEUR, de compter sur un hypothétique cache.. Et sur son utilisation... Et dans 99.99% des cas, tu liras une taille fausse (par exemple avec stat) justement parce que l'écriture n'est pas terminée...
Ben, du point de vue de l'utilisateur, tu sais que si un programme écrit dans un fichier et le ferme, puis que ce même programme (ou un autre) ouvre le fichier pour le lire, les modifications seront prises en compte TOUT DE SUITE.
Et tu sais aussi que tu ne dois pas retirer ta clé USB avant d'avoir dé-monté le volume ou d'avoir cliqué sur "retirer le périphérique en toute sécurité".
Donc, tout est logique, aussi bien du point de vue de l'OS (précédemment montré) que du point de vue de l'utilisateur.
À moins d'un bug de l'OS, la taille sera 5Mo, cache ou pas cache.Citation:
Admettons qu'un programme fasse ce que tu dis : ouvre un fichier, envoie 5 Megs à écrire, ouvre ce MEME fichier en lecture, veuille lire la taille...
réfère-toi au départ.Citation:
Envoyé par Médinoc
On ne parlait pas d'avoir fermé le fichier, mais de lire un fichier EN TRAIN D'ETRE ECRIT et NON FERME
Dans ce cas, on ne devrait même pas pouvoir l'ouvrir en lecture. Problème résolu sous Windows.
Ce que je fais souvent (tail -f sur des fichiers de log qui visiblement sont bufferises -- les ecritures arrivent par gros paquets qui coupent au milieu de n'importe quoi).Citation:
Envoyé par souviron34
Si tu lis et ecris dans un meme fichier, il peut y avoir un probleme de synchronisation, mais tous les OS que je connais donne une vue qui correspond aux operations reportees comme completes aux programmes, sans tenir compte d'une ecriture physique ou pas.
ben si..
Par exemple j'ai le cas :
Admettons qu'un programme ait une boucle infinie. Dans cette boucle, il écrit avec un seul ordre fwrite un gros volume, puis immédiatement effectue un stat et affiche la taille, pour lire ensuite les données...
A la vitesse de la majorité des CPU aujoudhui, le stat se fera AVANT que l'écriture physique soit faite (puisque avec un gros volume de données et la bufferisation, cela prendra du temps à écrire), et par conséquent la taille sera fausse..
Essaie. Tu peux te servir du programme que j'ai donne plus haut.Citation:
Envoyé par souviron34
Edit: je l'ai fait. Le comportement est bien celui auquel je m'attendais. stat est toujours coherent avec ce qui a ete ecrit.
NON.... D'accord pour le tail -f, faux (voir post précédent) si dans le même programme tu appelles par exemple stat..Citation:
Envoyé par Jean-Marc.Bourguet
Et même dans un autre programme....
(et en note, pour le tail -f, il y a 2 bufferisations (celle du write, et celle de la console)).