|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 | |
|
Member
Iscritto dal: Oct 2004
Città: Viterbo
Messaggi: 37
|
[c] Lettura di ESATTAMENTE un carattere da input
Premesso che già conosco le funzioni getc e fgetc, il problema che ho è il seguente: voglio creare una specie di menu del tipo [1.Accedi - 2.Esci] ed il programma dovrà reagire in base all'input d 1 o 2 (o altro). il mio problema è il bufer d caratteri della tastiera (credo) in quanto una volta preso un carattere da input il programma si comporta in modo corretto, mentre mettendo in ingresso una stringa (es '111') il programma consuma prima tutto il dato in ingresso prima d proseguire (come da es stampa 3 volte comando1 poi prosegue)
vi do un abbozzo di pseudocodice del realtivo programma (non il codice perchè mi insultereste per la mia programmazione 'ad occhio'): Quote:
giusto un abbozzo per dare un'idea. come posso implementare la laettura d 1 carattere soltanto, buttendo il resto ( e utilizzando funzioni 'sicure' che mi garantiscono di prendere un numero definito di byte in input)? ho provato mettendo vettori di char d 2 byte , con il primo significativo e sul secondo andavo a scrivere un EOF, ma nn sembrava curarsene + di tanto. il "comando1" in realtà sarebbe una fork seguita da una exec per un client. già che ci sono vi chiedo anche: se faccio una fork e sul figlio una exec, ilprocesso padre rimanente attivo, come si comportano i programmi? il figlio va sulla stessa shell o su un'altra istanza della shell? posso implementare accesso concorrente con questo metodo (es 2 utenti che utilizzano 2 client diversi generati dallo stesso padre)? ok mi sono reso conto di essermi espresso malissimo, ma non ho voglia di sistemare, accontentatevi [ambiente Linux/Unix]
__________________
Kill, it's such a friendly word |
|
|
|
|
|
|
#2 | |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Codice:
char comando;
...
comando = 0;
while (comando != 2)
{
printf("[1.Accedi - 2.Esci]");
comando = getchar();
/* Pulisco il buffer di input. */
while (getchar() != '\n');
if (isdigit(comando))
{
if (comando == 1)
{
printf("\nComando 1\n\n");
/* Operazioni varie... */
}
}
else
printf("\nComando non valido. Riprovare...\n\n");
}
...
return 0;
Quote:
EDIT: Per quanto riguarda la fork() (peraliamo quindi di unix/linux/e simili) prova questo semplice programma: Codice:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int pid, status;
if ((pid = fork()) == 0)
{
/* Sono il figlio. */
printf("Sono il figlio: pid %d\n\n", getpid());
execl("/bin/ls", "ls" "-l", "-a", (char *) 0);
/* Prova a mettere del codice qui sotto... */
}
else
{
/* Sono il padre. */
printf("Sono il padre: pid %d, pid del figlio %d\nAttendo la terminazione del figlio...\n\n", getpid(), pid);
wait(&status);
printf("Figlio terminato, uscita.\n");
}
return 0;
}
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson Ultima modifica di -fidel- : 28-10-2006 alle 18:56. |
|
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Oct 2004
Città: Viterbo
Messaggi: 37
|
si, so come funzionano fork ed exec, ma mi chiedevo se sulla stessa shell l'esecuzione dei due (amesso che rimangano entrambi attivi) è interlacciata o no, e mi chiedevo anche cosa succederebbe se si facesse partire un nuovo client tramite il processo padre (facendo una nuova fork + exec) mentre già c'è un figlio attivo
__________________
Kill, it's such a friendly word |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Quote:
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson |
|
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Oct 2004
Città: Viterbo
Messaggi: 37
|
si esattamente questo, grazie. devo implementare una lettura e scrittura su memoria condivisa (mem creata dal padre, lettura e scrittura fatte dai figli), com possibilità di concorrenza in lettura/scrittura/cancellazione (da gestire tramite semafori). in pratica quello che mi chiedo è come lanciare + istanze del processo figlio dallo stesso padre (in modo che + figli utilizzino la stessa memoria condivisa) e pensavo d farlo appunto lasciando aperto il padre in atesa di ordini (accedi-esci) ma non so se sarebbe una soluzione valida, oppure se mi converrebbe fare una chiamata shmget in modo non esclusivo e far partire + istanze "padri" ognuna che genera un filgio ed aspetta la terminazione (la mem condiisa creata è unica x tutti i processi così come i semafori o sbaglio?) anche se poi dovrei far sincronizzare i padri in modo chel'ultimo ke si chiude elimini la mem condivisa
__________________
Kill, it's such a friendly word Ultima modifica di megamello : 28-10-2006 alle 19:01. |
|
|
|
|
|
#6 | ||
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Quote:
Come descritto anche nella manpage di execve: Quote:
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson |
||
|
|
|
|
|
#7 |
|
Member
Iscritto dal: Oct 2004
Città: Viterbo
Messaggi: 37
|
si so della perdita, infatti la shm attach l'avrei messa sul figlio...cmq leggi il post sopra per favore, che dopo l'edit è diventato un poema
grazie di tutto l'aiuto cmq
__________________
Kill, it's such a friendly word |
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Quote:
In questo modo non hai alcun bisogno di usare memoria condivisa per far dialogare padre e figli: ti basta usare l'exit code del filgio per far capire al padre come è andata. Nel caso di un solo figlio (come si vede nel mio esempio), tramite la wait(&status) leggi in status il codice di ritorno del figlio (quello passato dalla return del figlio), se invece hai più figli, puoi usare la waitpid() oppure (molto meglio e più facile da gestire) usare una signal() sul segnale SIGCHLD per essere segnalati ogni qual volta un figlio termina (e nella routine di gestione del segnale puoi facilmente sapere il pid del figlio che ha terminato (ed ovviamente il suo exit code).
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson Ultima modifica di -fidel- : 28-10-2006 alle 19:15. |
|
|
|
|
|
|
#9 |
|
Member
Iscritto dal: Oct 2004
Città: Viterbo
Messaggi: 37
|
il fatto è che DEVO usare una memoria condivisa, in quanto i figli la devono usare come se fosse una bacheca per messaggi... sono fattibili le soluzioni che ho proposto prima?
__________________
Kill, it's such a friendly word |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Ti consiglio di fare come segue:
1) il padre (main) crea la memoria condivisa. 1) il padre crea i figli: tutti i figli ereditano automaticamente una copia del puntatore alla memoria condivisa 3) i figli (e il padre) accedono alla memoria condivisa in mutua esclusione (sezione critica). 4) il padre può controllare in qualunque momento la terminazione dei figli (ed il modo in cui sono terminati) tramite una signal() su SIGCHLD 5) Se i figli devono lanciare nuovi processi esterni, usa la system() invece della execve() (per avere il controllo del figlio anche dopo la terminazione del comando esterno).
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson |
|
|
|
|
|
#11 | |
|
Member
Iscritto dal: Oct 2004
Città: Viterbo
Messaggi: 37
|
Quote:
__________________
Kill, it's such a friendly word |
|
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Jan 2006
Messaggi: 2722
|
Quote:
EDIT: comunque io uso raramente (anzi direi quasi mai...) la memoria condivisa per far dialogare i processi (devi stare molto attento ad usarla per quanto riguarda la sicurezza), meglio usare pipes + semafori (implementati sempre con una pipe per semplicità) per far dialogare/scambiare dati tra più processi. Poi se ti è stato richiesto esplicitamente di usare la memoria condivisa, oppure ne hai assolutamente bisogno e non sai come fare altrimenti... (ma di solito si trova sempre un'alternativa, anche di uguale/minore complessità implementativa)
__________________
- Spesso gli errori sono solo i passi intermedi che portano al fallimento totale. - A volte penso che la prova piu' sicura che esiste da qualche parte una forma di vita intelligente e' il fatto che non ha mai tentato di mettersi in contatto con noi. -- Bill Watterson Ultima modifica di -fidel- : 28-10-2006 alle 20:35. |
|
|
|
|
|
|
#13 |
|
Member
Iscritto dal: Oct 2004
Città: Viterbo
Messaggi: 37
|
eh si è necessario utilizzare la mem condivisa da richiesta, deve essere usata tipo bacheca dai processi figli...ti rignrazio ancora per l'aiuto che mi hai dato, penso di essere a posto per ora
__________________
Kill, it's such a friendly word |
|
|
|
|
|
#14 | |
|
Member
Iscritto dal: Oct 2004
Città: Viterbo
Messaggi: 37
|
scusate ma ho ancora problemi...viposto direttamente il codice poi spiego...
Quote:
Allora, il programma (in particolare la funzione login() ) dovrebbe prendere 1 carattere in input e a seconda se sia 1, 2 o altro, dovrebbe stampare comando1, uscire o stampare Comando non valido ( e ciclare). funziona discretamente se non fosse che ha problemi con stringhe di più di un carattere, ossia, se passo stringhe di caratteri casuali in input stampa Comando nonvalido, ma se le stringhe iniziano con 1 o 2 , allora stampa comando1 nel primo caso ed esce nel secondo. come posso fare per evitare ciò? una domanda....il programma può generare inconsistenza sui dati? c'è pericolo che ciò che passo in ingresso venga memorizzato a partire da char comando e i caratteri seguenti il primo vadano a "sporcare" zone di memoria? utilizzo fgetc per evitare situazioni del genere, ma vorrei avere la certezza.... grazie a tutti per l'aiuto
__________________
Kill, it's such a friendly word |
|
|
|
|
|
|
#15 |
|
Member
Iscritto dal: Oct 2004
Città: Viterbo
Messaggi: 37
|
*UP*
__________________
Kill, it's such a friendly word |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:34.



















