2016-12-08 1 views
3

J'ai rencontré un problème lors de l'utilisation de scanf dans un nouveau processus, créé avec fork(). Scanf n'est pas bloqué, donc printf est appelé encore et encore.

Voici un échantillon du code:

Printf appelé avant scanf dans un processus fourchu dans C

int main(int argc,char *argv[]) 
{ 
    switch(fork()) { 
     case 0: 
      while(1) { 
       char buffer[100]; 
       scanf("%s",buffer); 
       printf("Input was %s\n",buffer); 
      } 
    } 
    return 0; 
} 

Quelqu'un sait comment résoudre ce problème simple? (Certaines parties du code sont manquantes, je Shrinked le code à un minimum pour ce problème)

+0

Votre nouveau processus n'a aucune interface, donc scanf ne peut pas scanner. – Joshpbarron

+0

comment est-ce que je peux attacher l'interface à lui? @Joshpbarron –

+0

Pourquoi ne numérisez-vous pas dans le processus père? – Boiethios

Répondre

1

Le problème est dans le code que vous en commentaires pour faire l'exemple minimal, en cours d'exécution cela fonctionne parfaitement bien

#include <stdio.h> 

int main(int argc,char *argv[]) 
{ 
    switch(fork()) { 
     case 0: 
      while(1) { 
       char buffer[100]; 
       scanf("%s",buffer); 
       printf("Input was %s\n",buffer); 
      } 
      break; 
     default: 
      sleep(100); 
      break; 
    } 
    return 0; 
} 

Je suppose qu'avec votre code complet autour de votre appel fork il y a aussi une fermeture de fichiers pour créer le sous-processus et le détacher du terminal - c'est la fermeture de stdin et le détachement du terminal qui fait échouer scanf.

+1

La fourche ne se détache pas du terminal, mais la coquille rouvre une nouvelle stdin pour lire la commande suivante et précédente est fermé –

+0

Oui - fourche en elle-même ne ferme rien - je faisais allusion à la partie de la code qu'il avait commenté - va essayer de voir si je peux clarifier – Soren

0

Le vrai problème est que le processus parent retourne immédiatement. Le shell prend alors l'entrée standard pour lire une nouvelle commande. Vous pouvez facilement demonstate avec un court sommeil dans parent:

switch(fork()) { 
    case 0: 
     while(1) { 
      char buffer[100]; 
      int cr = scanf("%s",buffer); 
      printf("Input was %s (%d)\n",buffer, cr); 
      if (cr <= 0) break; 
     } 
    } 
    break; 
default: 
    sleep(5); 
    printf("Done\n"); 
} 

Pendant les 5 secondes où le parent dort, vous pouvez interagir normalement avec l'enfant. Ensuite, lorsque le parent se termine, l'entrée pour l'enfant est fermée et scanf renvoie -1.