J'expérimente avec du code C pour l'implémentation de shell et fgets trouvé() retourne des lignes dupliquées quand après je lance un processus, que je ne pouvais pas comprendre, et j'apprécierais grandement toute aide .La lecture d'une entrée à l'aide de fgets retourne des lignes dupliquées dans C
Ma question est: le forking change-t-il l'offset dans tous les fichiers ouverts dans le processus parent? Cela semble se produire dans mon programme.
DE LA réponse ci-dessous @Vadim Ponomarev et ma compréhension: fgets() n'est pas thread-safe (ou à proprement parler, il est, mais bifurquer un processus provoque l'stdin à initialiser en quelque sorte, ce qui le changement du décalage de fichier partagé).
Le code va comme ceci:
int main() {
char buf[200];
int r;
pid_t pid = 0;
while(getcmd(buf, 200, pid) >= 0) {
fprintf(stderr, "current pid: %d\n", getpid());
pid = fork();
// Without forking the fgets() reads all lines normally
if(pid == 0)
exit(0);
wait(&r);
}
return 0;
}
La fonction getcmd() est juste un emballage:
int
getcmd(char *buf, int nbuf, pid_t pid)
{
memset(buf, 0, nbuf);
if (fgets(buf, nbuf, stdin) == NULL) {
fprintf(stderr, "EOF !!!\n");
return -1;
}
fprintf(stderr, "pid: %d -- getcmd buf ======= --> %s\n", getpid(), buf);
return 0;
}
J'ai aussi un fichier d'entrée temp avec quelques textes aléatoires:
line 1
line 2
line 3
Après la compilation, et je cours a.out < temp, la sortie indique que 6 lignes sont imprimées et généralement certaines lignes sont dupliquées. Mais si je supprime la ligne
pid = fork()
...
alors la sortie devient normal (juste montrer toutes les lignes, un par un, ce qui signifie fgets() est appelé 3 fois).
Une idée de ce qui ne va pas?
sortie (ce que a):
pid: 10361 -- getcmd buf ======= --> line1
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line2
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line3
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line2
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line3
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line3
current pid: 10361
EOF !!!
Et je me attends à ceci:
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line1
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line2
current pid: 10361
pid: 10361 -- getcmd buf ======= --> line3
EOF
Une version compilable pour référence:
#include <stdio.h>
#include <stdlib.h>
#include <wait.h>
#include <zconf.h>
#include <unistd.h>
#include <memory.h>
int
getcmd(char *buf, int nbuf, pid_t pid)
{
memset(buf, 0, nbuf);
if (fgets(buf, nbuf, stdin) == NULL) {
fprintf(stderr, "EOF !!!\n");
return -1;
}
fprintf(stderr, "pid: %d -- getcmd buf ======= --> %s\n", getpid(), buf);
return 0;
}
int main() {
char buf[200];
int r;
pid_t pid = 0;
while(getcmd(buf, 200, pid) >= 0) {
fprintf(stderr, "current pid: %d\n", getpid());
pid = fork();
// Without forking the fgets() reads all lines normally
if(pid == 0)
exit(0);
wait(&r);
}
return 0;
}
Merci!
Pouvez-vous s'il vous plaît modifier votre question pour * montrer * la sortie réelle (et attendue) (en entier, copier-coller comme texte)? Veuillez également inclure un exemple réel [minimal, complet et vérifiable] (http://stackoverflow.com/help/mcve), quelque chose que nous pouvons facilement copier et tester nous-mêmes. –
@Someprogrammerdude Bonjour, j'ai ajouté les sorties. En un mot, je ne m'attendais pas à voir des lignes en double lues. –
parent et enfant partagent le même descripteur de fichier, qu'est-ce que vous attendez dans la fourchette sur le stdin? –