Pages: [1] 2 3   Go Down
Print
Author Topic: Programmazione C: domande  (Read 12307 times)
0 Members e 1 Utente non registrato stanno visualizzando questa discussione.
milos224
Forumista
***
Offline Offline

Posts: 830


« on: 17-07-2012, 15:27:42 »

In vista dell'esame ho due domande riguardo la programmazione C:

1) Non ho capito a che serve la chiamata "close()". Se in codice dove ci sono varie printf, inserisco un solo "close(1)" come mai il codice non stampa nessuna print? a cosa serve il close(1)?

2)Numero processi in un codice.
Se io ho il seguente codice
Code:
int main(){
    
    printf("ciao");
    pid_t pid;
    pid = fork();
  
}
quanti processi ho nel codice? Inoltre il main è contato come processo?

3)Come si implementa l'operazione di wait(o signal) su un semaforo in c?
« Last Edit: 17-07-2012, 15:29:52 by milos224 » Logged
ɹǝǝuıƃuǝsɹǝʌǝɹ
Administrator
God of the Forum
*****
Offline Offline

Gender: Male
Posts: 4.475


Più grande è la lotta, e più è glorioso il trionfo


WWW
« Reply #1 on: 17-07-2012, 15:41:06 »

1) Non ho capito a che serve la chiamata "close()". Se in codice dove ci sono varie printf, inserisco un solo "close(1)" come mai il codice non stampa nessuna print? a cosa serve il close(1)?
Pre-qequisiti per la comprensione della risposta:
- descrittori di file
- chiamate di sistema (syscall)
- funzione di libreria standard printf
Risposta
Se ti manca almeno un prerequisito, il consiglio è di studiare prima quello. Se li hai tutti, allora la risposta sarà esauriente .

2)Numero processi in un codice.
Se io ho il seguente codice
Code:
int main(){
    
    printf("ciao");
    pid_t pid;
    pid = fork();
  
}
quanti processi ho nel codice? Inoltre il main è contato come processo?
Pre-requisiti per la comprensione della risposta:
- processi
- funzioni
- multi threading su sistemi Unix-like.
La risposta è 2. Il main non è un processo, e non può essere contato come tale.
Risposta lunga
Logged

La grande marcia della distruzione mentale proseguirà. Tutto verrà negato. Tutto diventerà un credo. È un atteggiamento ragionevole negare l'esistenza delle pietre sulla strada; sarà un dogma religioso affermarla. È una tesi razionale pensare di vivere tutti in un sogno; sarà un esempio di saggezza mistica affermare che siamo tutti svegli. Accenderemo fuochi per testimoniare che due più due fa quattro. Sguaineremo spade per dimostrare che le foglie sono verdi in estate. Non ci resterà quindi che difendere non solo le incredibili virtù e saggezze della vita umana, ma qualcosa di ancora più incredibile: questo immenso, impossibile universo che ci guarda dritto negli occhi. Combatteremo per i prodigi visibili come se fossero invisibili. Guarderemo l'erba e i cieli impossibili con uno strano coraggio. Saremo tra coloro che hanno visto eppure hanno creduto.

In tutto, amare e servire.

  
                            ن                           
I can deal with ads,
I can deal with buffer,
but when ads buffer
I suffer...

...nutrimi, o Signore, "con il pane delle lacrime; dammi, nelle lacrime, copiosa bevanda...

   YouTube 9GAG    anobii  S  Steam T.B.o.I. Wiki [univ] Lezioni private  ʼ  Albo d'Ateneo Unicode 3.0.1
Usa "Search" prima di aprire un post - Scrivi sempre nella sezione giusta - Non spammare - Rispetta gli altri utenti - E ricorda di seguire il Regolamento
milos224
Forumista
***
Offline Offline

Posts: 830


« Reply #2 on: 17-07-2012, 15:53:38 »

1) Non ho capito a che serve la chiamata "close()". Se in codice dove ci sono varie printf, inserisco un solo "close(1)" come mai il codice non stampa nessuna print? a cosa serve il close(1)?
Pre-qequisiti per la comprensione della risposta:
- descrittori di file
- chiamate di sistema (syscall)
- funzione di libreria standard printf
Risposta
Se ti manca almeno un prerequisito, il consiglio è di studiare prima quello. Se li hai tutti, allora la risposta sarà esauriente .

2)Numero processi in un codice.
Se io ho il seguente codice
Code:
int main(){
    
    printf("ciao");
    pid_t pid;
    pid = fork();
  
}
quanti processi ho nel codice? Inoltre il main è contato come processo?
Pre-requisiti per la comprensione della risposta:
- processi
- funzioni
- multi threading su sistemi Unix-like.
La risposta è 2. Il main non è un processo, e non può essere contato come tale.
Risposta lunga
Grazie reverse per la risposta!I prerequisiti che dici li ho studiati ma non li ho capiti..

Primo esempio)
Il descrittore di file è un intero non negativo che rappresenta un il canale di input/output. E 1 è lo standard output. Questo vuol dire che in un qualunque codice dove ci sia close(1) non c'è output?
Se io ho il seguente codice
Code:
int main(){
   
    printf("ciao");
    close(1);
    printf("rosso");
   
}
perchè non stampa nulla?

Secondo punto)
La tua risposta è 2. Ma 2 considerando solo la linea della chiamata fork, dato che duplica il processo?
Logged
ɹǝǝuıƃuǝsɹǝʌǝɹ
Administrator
God of the Forum
*****
Offline Offline

Gender: Male
Posts: 4.475


Più grande è la lotta, e più è glorioso il trionfo


WWW
« Reply #3 on: 18-07-2012, 01:52:16 »

perchè non stampa nulla?
Il buffer/file/stream su cui la funzione di libreria printf scrive (e che sversa dentro il descrittore di file numero 1, chiamato anche stdout = standard output), non viene svuotato automaticamente ad ogni invocazione, perciò normalmente in C si aspetta il successivo carattere di ritorno a capo \n (ascii 13 decimale) per farlo.
Se vuoi costringere uno svuotamento del buffer puoi usare la funzione di libreria standard fflush passandole come parametro proprio stdout.

Oppure puoi prependere (accodare) un \n alla fine della stringa passata alla prima invocazione di printf (ma così introduci un "a-capo" cambiando di fatto l'output previsto dalla prima versione del codice).

[...]

Per evitare di dover passare attraverso questi problemi legati alla particolare implementazione delle strutture FILE (*), prova a scrivere direttamente con la syscall write (che non richiede nemmeno che le stringhe, anzi i buffer di byte, da scrivere siano terminate da carattere NULL \0  ok), con una scrittura del tipo
Code:
char [] stringa = "ciao";
write (1, stringa, 4);
//oppure
write (1, stringa, strlen (stringa)) //questa invocazione richiede l'inclusione di <string.h>

//questa versione non usa una stringa C (terminata da byte nullo), ma funziona comunque.
//NON vi si può applicare strlen per contarne i caratteri, perché nessuno garantisce che ci sia un byte nullo dopo la 'o'
char [] stringa = {'c', 'i', 'a', 'o'};
write (1, stringa, 4);

Secondo punto)
La tua risposta è 2. Ma 2 considerando solo la linea della chiamata fork, dato che duplica il processo?
Esattamente. Dal momento in cui la chiamata a fork (invocazione) restituisce senza errori, ci sono esattamente due processi identici, tranne per il fatto che uno è genitore (padre) e l'altro figlio.
Logged

La grande marcia della distruzione mentale proseguirà. Tutto verrà negato. Tutto diventerà un credo. È un atteggiamento ragionevole negare l'esistenza delle pietre sulla strada; sarà un dogma religioso affermarla. È una tesi razionale pensare di vivere tutti in un sogno; sarà un esempio di saggezza mistica affermare che siamo tutti svegli. Accenderemo fuochi per testimoniare che due più due fa quattro. Sguaineremo spade per dimostrare che le foglie sono verdi in estate. Non ci resterà quindi che difendere non solo le incredibili virtù e saggezze della vita umana, ma qualcosa di ancora più incredibile: questo immenso, impossibile universo che ci guarda dritto negli occhi. Combatteremo per i prodigi visibili come se fossero invisibili. Guarderemo l'erba e i cieli impossibili con uno strano coraggio. Saremo tra coloro che hanno visto eppure hanno creduto.

In tutto, amare e servire.

  
                            ن                           
I can deal with ads,
I can deal with buffer,
but when ads buffer
I suffer...

...nutrimi, o Signore, "con il pane delle lacrime; dammi, nelle lacrime, copiosa bevanda...

   YouTube 9GAG    anobii  S  Steam T.B.o.I. Wiki [univ] Lezioni private  ʼ  Albo d'Ateneo Unicode 3.0.1
Usa "Search" prima di aprire un post - Scrivi sempre nella sezione giusta - Non spammare - Rispetta gli altri utenti - E ricorda di seguire il Regolamento
milos224
Forumista
***
Offline Offline

Posts: 830


« Reply #4 on: 18-07-2012, 08:12:30 »

perchè non stampa nulla?
Il buffer/file/stream su cui la funzione di libreria printf scrive (e che sversa dentro il descrittore di file numero 1, chiamato anche stdout = standard output), non viene svuotato automaticamente ad ogni invocazione, perciò normalmente in C si aspetta il successivo carattere di ritorno a capo \n (ascii 13 decimale) per farlo.
Se vuoi costringere uno svuotamento del buffer puoi usare la funzione di libreria standard fflush passandole come parametro proprio stdout.

Oppure puoi prependere (accodare) un \n alla fine della stringa passata alla prima invocazione di printf (ma così introduci un "a-capo" cambiando di fatto l'output previsto dalla prima versione del codice).

[...]

Per evitare di dover passare attraverso questi problemi legati alla particolare implementazione delle strutture FILE (*), prova a scrivere direttamente con la syscall write (che non richiede nemmeno che le stringhe, anzi i buffer di byte, da scrivere siano terminate da carattere NULL \0  ok), con una scrittura del tipo
Code:
char [] stringa = "ciao";
write (1, stringa, 4);
//oppure
write (1, stringa, strlen (stringa)) //questa invocazione richiede l'inclusione di <string.h>

//questa versione non usa una stringa C (terminata da byte nullo), ma funziona comunque.
//NON vi si può applicare strlen per contarne i caratteri, perché nessuno garantisce che ci sia un byte nullo dopo la 'o'
char [] stringa = {'c', 'i', 'a', 'o'};
write (1, stringa, 4);

Secondo punto)
La tua risposta è 2. Ma 2 considerando solo la linea della chiamata fork, dato che duplica il processo?
Esattamente. Dal momento in cui la chiamata a fork (invocazione) restituisce senza errori, ci sono esattamente due processi identici, tranne per il fatto che uno è genitore (padre) e l'altro figlio.
Perció basta un close(1) per non far stampare nulla, anche se dopo ho altre print?
Logged
ɹǝǝuıƃuǝsɹǝʌǝɹ
Administrator
God of the Forum
*****
Offline Offline

Gender: Male
Posts: 4.475


Più grande è la lotta, e più è glorioso il trionfo


WWW
« Reply #5 on: 18-07-2012, 09:27:38 »

Sì, scusa ieri sera era tardi e non avevo ben letto la domanda.

Non dovrebbe non stampare nulla: almeno il printf invocato precedentemente alla close doveva stamparlo, però siccome il buffer non era stato svuotato sembrava che non avesse stampato nulla.

Comunque, sì, una volta chiuso il descrittore di file, tutte le scritture su di esso non produrranno nulla (se non un errore).
Logged

La grande marcia della distruzione mentale proseguirà. Tutto verrà negato. Tutto diventerà un credo. È un atteggiamento ragionevole negare l'esistenza delle pietre sulla strada; sarà un dogma religioso affermarla. È una tesi razionale pensare di vivere tutti in un sogno; sarà un esempio di saggezza mistica affermare che siamo tutti svegli. Accenderemo fuochi per testimoniare che due più due fa quattro. Sguaineremo spade per dimostrare che le foglie sono verdi in estate. Non ci resterà quindi che difendere non solo le incredibili virtù e saggezze della vita umana, ma qualcosa di ancora più incredibile: questo immenso, impossibile universo che ci guarda dritto negli occhi. Combatteremo per i prodigi visibili come se fossero invisibili. Guarderemo l'erba e i cieli impossibili con uno strano coraggio. Saremo tra coloro che hanno visto eppure hanno creduto.

In tutto, amare e servire.

  
                            ن                           
I can deal with ads,
I can deal with buffer,
but when ads buffer
I suffer...

...nutrimi, o Signore, "con il pane delle lacrime; dammi, nelle lacrime, copiosa bevanda...

   YouTube 9GAG    anobii  S  Steam T.B.o.I. Wiki [univ] Lezioni private  ʼ  Albo d'Ateneo Unicode 3.0.1
Usa "Search" prima di aprire un post - Scrivi sempre nella sezione giusta - Non spammare - Rispetta gli altri utenti - E ricorda di seguire il Regolamento
milos224
Forumista
***
Offline Offline

Posts: 830


« Reply #6 on: 18-07-2012, 09:43:16 »

Sì, scusa ieri sera era tardi e non avevo ben letto la domanda.

Non dovrebbe non stampare nulla: almeno il printf invocato precedentemente alla close doveva stamparlo, però siccome il buffer non era stato svuotato sembrava che non avesse stampato nulla.

Comunque, sì, una volta chiuso il descrittore di file, tutte le scritture su di esso non produrranno nulla (se non un errore).
Grazie ancora per le risposte. Ma per aprire il descrittore invece? open(1) non credo possa andare bene..
Logged
milos224
Forumista
***
Offline Offline

Posts: 830


« Reply #7 on: 19-07-2012, 12:02:51 »

Per implementare l'operazione di wait ( o signal) su un semaforo devo usare la chiamata di sistema "semop"?
Nelle slide del prof questa è la chiamata:
int semop(int semid, struct sembuf *ops, unsigned nops) dove semid è il descrittore del semaforo,ops punta ad un vettore formato da una o più istanze di una struttura standard e nops contiene il numero di elementi del vettore puntato da ops.

Logged
Chuck_son
Forumista Eroico
*****
Offline Offline

Gender: Male
Posts: 1.583



WWW
« Reply #8 on: 19-07-2012, 21:47:48 »

Per implementare l'operazione di wait ( o signal) su un semaforo devo usare la chiamata di sistema "semop"?
Nelle slide del prof questa è la chiamata:
int semop(int semid, struct sembuf *ops, unsigned nops) dove semid è il descrittore del semaforo,ops punta ad un vettore formato da una o più istanze di una struttura standard e nops contiene il numero di elementi del vettore puntato da ops.


si esatto, non ci sono chiamate "native" di wait e signal
Logged

Aliens Exist
milos224
Forumista
***
Offline Offline

Posts: 830


« Reply #9 on: 20-07-2012, 13:38:33 »

Ritorno sugli argomenti con 2 domande:
1) Per quanto riguarda la domanda sulla close(1), se ho capito bene il modo per riaprire l'output è open(1).
Questo codice allora perchè non stampa nulla?
Code:
int main(){
   
    printf("ciao");
    close(1);
    open(1);
    printf("eii");
    printf("rosso");
   
}

2)Domanda sulla fork().
Questo codice
Code:
int main(){
   
    printf("ciao");
    pid_t pid; pid_t pid2;
    pid = fork();
    pid2=fork();
}
ha 3 processi?
Logged
ɹǝǝuıƃuǝsɹǝʌǝɹ
Administrator
God of the Forum
*****
Offline Offline

Gender: Male
Posts: 4.475


Più grande è la lotta, e più è glorioso il trionfo


WWW
« Reply #10 on: 20-07-2012, 14:20:55 »

1) Per quanto riguarda la domanda sulla close(1), se ho capito bene il modo per riaprire l'output è open(1).
Questo codice allora perchè non stampa nulla?
Code:
int main(){
   
    printf("ciao");
    close(1);
    open(1);
    printf("eii");
    printf("rosso");
   
}
A meno che tu non abbia creato una tua funzione personale che si chiama proprio open, quel codice non compila.
Sinceramente non ricordo come fare a riaprire lo standard output una volta chiuso, ma di certo bisogna specificare un qualche tipo di PATH nella sintassi di open.

Questo codice
Code:
int main(){
   
    printf("ciao");
    pid_t pid; pid_t pid2;
    pid = fork();
    pid2=fork();
}
ha 3 processi?
Sì.
Logged

La grande marcia della distruzione mentale proseguirà. Tutto verrà negato. Tutto diventerà un credo. È un atteggiamento ragionevole negare l'esistenza delle pietre sulla strada; sarà un dogma religioso affermarla. È una tesi razionale pensare di vivere tutti in un sogno; sarà un esempio di saggezza mistica affermare che siamo tutti svegli. Accenderemo fuochi per testimoniare che due più due fa quattro. Sguaineremo spade per dimostrare che le foglie sono verdi in estate. Non ci resterà quindi che difendere non solo le incredibili virtù e saggezze della vita umana, ma qualcosa di ancora più incredibile: questo immenso, impossibile universo che ci guarda dritto negli occhi. Combatteremo per i prodigi visibili come se fossero invisibili. Guarderemo l'erba e i cieli impossibili con uno strano coraggio. Saremo tra coloro che hanno visto eppure hanno creduto.

In tutto, amare e servire.

  
                            ن                           
I can deal with ads,
I can deal with buffer,
but when ads buffer
I suffer...

...nutrimi, o Signore, "con il pane delle lacrime; dammi, nelle lacrime, copiosa bevanda...

   YouTube 9GAG    anobii  S  Steam T.B.o.I. Wiki [univ] Lezioni private  ʼ  Albo d'Ateneo Unicode 3.0.1
Usa "Search" prima di aprire un post - Scrivi sempre nella sezione giusta - Non spammare - Rispetta gli altri utenti - E ricorda di seguire il Regolamento
milos224
Forumista
***
Offline Offline

Posts: 830


« Reply #11 on: 20-07-2012, 14:29:03 »

1) Per quanto riguarda la domanda sulla close(1), se ho capito bene il modo per riaprire l'output è open(1).
Questo codice allora perchè non stampa nulla?
Code:
int main(){
    
    printf("ciao");
    close(1);
    open(1);
    printf("eii");
    printf("rosso");
    
}
A meno che tu non abbia creato una tua funzione personale che si chiama proprio open, quel codice non compila.
Sinceramente non ricordo come fare a riaprire lo standard output una volta chiuso, ma di certo bisogna specificare un qualche tipo di PATH nella sintassi di open.

Questo codice
Code:
int main(){
    
    printf("ciao");
    pid_t pid; pid_t pid2;
    pid = fork();
    pid2=fork();
}
ha 3 processi?
Sì.
Reverse quel codice a me compila, cioè errori non me ne da e non ho creato nulla. Non stampa nulla però.

Riguardo inoltre la seconda domanda: ho 3 processi, che sono dati due dalla fork e uno dal processo del metodo stesso? Cioè le due fork duplicano lo stesso processo?
« Last Edit: 20-07-2012, 14:30:36 by milos224 » Logged
Sickboy
Matricola
*
Offline Offline

Gender: Male
Posts: 41



« Reply #12 on: 20-07-2012, 22:50:57 »

La chiamata fork() non fa altro che duplicare un processo. Dopo tale chiamata , se avvenuta con successo, vengono generati due processi, il processo padre e il processo figlio.
Quindi ad ogni fork() sono generati 2 processi.   ciao
Logged
ɹǝǝuıƃuǝsɹǝʌǝɹ
Administrator
God of the Forum
*****
Offline Offline

Gender: Male
Posts: 4.475


Più grande è la lotta, e più è glorioso il trionfo


WWW
« Reply #13 on: 20-07-2012, 23:28:01 »

Reverse quel codice a me compila, cioè errori non me ne da e non ho creato nulla. Non stampa nulla però.
Prova a compilare con -Wall -Werror e scoprirai almeno 3 cose che non vanno bene (tutte della stessa natura).

Riguardo inoltre la seconda domanda: ho 3 processi, che sono dati due dalla fork e uno dal processo del metodo stesso? Cioè le due fork duplicano lo stesso processo?
La chiamata fork() non fa altro che duplicare un processo. Dopo tale chiamata , se avvenuta con successo, vengono generati due processi, il processo padre e il processo figlio.
Quindi ad ogni fork() sono generati 2 processi.   ciao
In realtà il processo generato è solo uno (il figlio), l'altro (il padre) esisteva già e mantiene il PID che aveva prima della invocazione a fork.
Quindi è un padre che genera due figli, che potremmo dire essere inconsciamente fratelli boh.
Logged

La grande marcia della distruzione mentale proseguirà. Tutto verrà negato. Tutto diventerà un credo. È un atteggiamento ragionevole negare l'esistenza delle pietre sulla strada; sarà un dogma religioso affermarla. È una tesi razionale pensare di vivere tutti in un sogno; sarà un esempio di saggezza mistica affermare che siamo tutti svegli. Accenderemo fuochi per testimoniare che due più due fa quattro. Sguaineremo spade per dimostrare che le foglie sono verdi in estate. Non ci resterà quindi che difendere non solo le incredibili virtù e saggezze della vita umana, ma qualcosa di ancora più incredibile: questo immenso, impossibile universo che ci guarda dritto negli occhi. Combatteremo per i prodigi visibili come se fossero invisibili. Guarderemo l'erba e i cieli impossibili con uno strano coraggio. Saremo tra coloro che hanno visto eppure hanno creduto.

In tutto, amare e servire.

  
                            ن                           
I can deal with ads,
I can deal with buffer,
but when ads buffer
I suffer...

...nutrimi, o Signore, "con il pane delle lacrime; dammi, nelle lacrime, copiosa bevanda...

   YouTube 9GAG    anobii  S  Steam T.B.o.I. Wiki [univ] Lezioni private  ʼ  Albo d'Ateneo Unicode 3.0.1
Usa "Search" prima di aprire un post - Scrivi sempre nella sezione giusta - Non spammare - Rispetta gli altri utenti - E ricorda di seguire il Regolamento
milos224
Forumista
***
Offline Offline

Posts: 830


« Reply #14 on: 21-07-2012, 00:02:55 »

Reverse quel codice a me compila, cioè errori non me ne da e non ho creato nulla. Non stampa nulla però.
Prova a compilare con -Wall -Werror e scoprirai almeno 3 cose che non vanno bene (tutte della stessa natura).
Ma esiste un modo per "riaprire" l'output?
Riguardo inoltre la seconda domanda: ho 3 processi, che sono dati due dalla fork e uno dal processo del metodo stesso? Cioè le due fork duplicano lo stesso processo?
La chiamata fork() non fa altro che duplicare un processo. Dopo tale chiamata , se avvenuta con successo, vengono generati due processi, il processo padre e il processo figlio.
Quindi ad ogni fork() sono generati 2 processi.   ciao
In realtà il processo generato è solo uno (il figlio), l'altro (il padre) esisteva già e mantiene il PID che aveva prima della invocazione a fork.
Quindi è un padre che genera due figli, che potremmo dire essere inconsciamente fratelli boh.
Si, infatti. In questo caso il processo che viene duplicato è il processo stesso dentro il main? Se noi scriviamo 20 fork, tutte dentro lo stesso metodo, i processi saranno 21 giusto?
Logged
Pages: [1] 2 3   Go Up
Print
Jump to: