PDA

View Full Version : [C]Progettare un buon programma


clockover
22-02-2010, 10:41
Devo fare un progetto in C per l'università! Un po di tempo fa avevo anche chiesto alcuni consigli! Oggi comincio! Volevo sapere se c'erano dei metodi per la progettazione! Ad esempio per Java conosco UML e mi sono trovato molto bene per la progettazione di applicazioni anche con un numero molto elevato di classi! Per quanto riguarda invece il C esiste qualche cosa del genere? O magari anche solo dei consigli sui passi da fare per la scrittura del codice! Non vorrei fare troppa confusione dato che è il mio primo progetto in C e sicuramente avrò molto da scrivere!
Grazie :D

carlito9987
23-02-2010, 11:40
Tanto per iniziare non pensare minimamente alle classi..... ti crea solo confusione. C non è un linguaggio object oriented, ma procedurale.

E' buona norma analizzare per bene il problema prima di iniziare a scrivere codice, molti sbagliano e presi dalla fretta iniziano a programmare andando a tentativi :muro: ... poi ti rendi conto che hai sbagliato tutto e provi a mettere toppe finchè non capisci che devi praticamente ricominciare da zero! :cry:

Dopo aver fatto una bella e corposa analisi, prendi foglio e penna ed inizia con la pseudocodifica... Ti facilita un bel pò le cose, gli errori più grossolani li riesci ad identificare in questa fase.. Vantaggi? Non dovrai riscrivere tutto il codice! Inoltre in questa fase decidi anche le strutture dati che andrai ad utilizzare..

Dopo aver fatto questo puoi cominciare con il codice.... Ricorda sempre:
- Header file
- Variabili Globali
- Strutture
- Prototipi
- Corpo del programma

Se posso darti qualche altro consiglio rimango a disposizione... Ciao e in bocca al lupo!! :D

clockover
23-02-2010, 12:49
Tanto per iniziare non pensare minimamente alle classi.....
No vabbè ho parlato di UML non per pensare alle classi ma giusto per fare un esempio :D :D !
E' buona norma analizzare per bene il problema prima di iniziare a scrivere codice, molti sbagliano e presi dalla fretta iniziano a programmare andando a tentativi ... poi ti rendi conto che hai sbagliato tutto e provi a mettere toppe finchè non capisci che devi praticamente ricominciare da zero!
Esatto proprio questo è il problema!

Ora comincio a buttare giù qualche riga di progetto e poi ti faccio sapere se ho problemi... :D :D Grazie mille!

carlito9987
23-02-2010, 14:09
Sai quante volte è capitato a me!!! :ncomment:

Dopo un pò capisci che una buona analisi ti fa risparmiare la metà del tempo! :D

Per qualsiasi cosa chiedi pure.... C lo uso abbastanza in questo periodo.

clockover
23-02-2010, 14:14
Grandi raga :D :D

eraser
23-02-2010, 14:20
Dopo un pò capisci che una buona analisi ti fa risparmiare la metà del tempo! :D

Concordo. Una buona analisi mentale (magari anche un T.S.O) prima di scrivere programmi in C è fondamentale per capire il perché ti stai per buttare in tale ambizioso progetto :D

PS: scherzo :D è una battuta, scrivo letteralmente solo in C, lo amo :D

carlito9987
23-02-2010, 16:25
Se il TSO è quello che ho capito io..... Concordo!! :D

WarDuck
23-02-2010, 16:27
Quotone, per l'università abbiamo scritto un programma peer2peer sotto linux, e carta e penna sono fondamentali per poter affrontare progetti di un certo tipo.

clockover
25-02-2010, 13:27
Ora mi trovo davanti a un piccolo dilemma!

Devo decidere se gestire i client che vogliono connettersi con i thread oppure creare dei figli con fork!

Il problema in definitiva qual'è! Se io ho delle variabili globali con le fork saranno modificate sia dal padre che dai figli! Solo che il padre continuerà a vederle come le modifica lui e il figlio altrettanto dato che effettivamente con la fork sto creando un nuovo processo! Per ovviare a questa cosa dovrei utilizzare uno spazio di memoria condivisa con shmget! Utilizzando i thread questa cosa non succede! Anche dalla vostra esperienza secondo voi cosa potrebbe essere meglio usare??
Con i thread avrei maggiori performance aumentando un po la complessità comunque!

WarDuck
25-02-2010, 15:04
Io dico di utilizzare i thread.

Se stai sotto linux, c'è l'ottima libreria pthread.

Non è così complesso gestirli con quella libreria.

Tommo
25-02-2010, 15:17
Io per i thread sto usando Boost::thread...
certo Boost è una roba immensa e ridondante, ma Thread fa proprio il suo dovere.
Non devi impararti assolutamente niente se non i concetti di alto livello (mutex, concorrenza, starving etc)... che possono uscire fuori quando hai una condivisione delle risorse.

Basta che dichiari un operatore overloaded "()" nella tua classe e chiami:
thread( boost::ref( ilTuoOggetto ) );

Questo crea il thread e ci esegue dentro l'operatore () sull'oggetto passato.
Molto comodo :D

EDIT: Ops Boost è C++. Come non detto :asd:

clockover
25-02-2010, 17:08
Io per i thread sto usando Boost::thread...
certo Boost è una roba immensa e ridondante, ma Thread fa proprio il suo dovere.
Non devi impararti assolutamente niente se non i concetti di alto livello (mutex, concorrenza, starving etc)... che possono uscire fuori quando hai una condivisione delle risorse.

Basta che dichiari un operatore overloaded "()" nella tua classe e chiami:
thread( boost::ref( ilTuoOggetto ) );

Questo crea il thread e ci esegue dentro l'operatore () sull'oggetto passato.
Molto comodo :D

EDIT: Ops Boost è C++. Come non detto :asd:
:D :D :D :D


Ho cominciato a scrivere del codice! Io sono sempre stato per i thread però un mio amico mi aveva fatto cambiare idea neanche ricordo per quale motivo però! Comunque ora ci rifletto un po su! Mi faccio una lista di pro e contro!

bobbytre
25-02-2010, 17:18
Io dico di utilizzare i thread.

Se stai sotto linux, c'è l'ottima libreria pthread.

Non è così complesso gestirli con quella libreria.


anche sotto windows con pthread-w32 ( http://sourceware.org/pthreads-win32/ )

WarDuck
25-02-2010, 17:35
:D :D :D :D


Ho cominciato a scrivere del codice! Io sono sempre stato per i thread però un mio amico mi aveva fatto cambiare idea neanche ricordo per quale motivo però! Comunque ora ci rifletto un po su! Mi faccio una lista di pro e contro!

IMHO un paio di motivi che potrebbero farti propendere per usare processi anziché threads:

- Devi gestire un numero fisso di processi/thread e magari li crei tutti subito senza gestirli dinamicamente: in quel caso la differenza di tempo tra la creazione di processi e la creazione di thread è tutto sommato irrilevante.

- I processi ti consentono maggiore stabilità poiché ognuno gira in uno spazio di memoria separato (per questo in IE8 ogni tab è un processo).

Viceversa se devi gestire un alto numero di richieste, dinamicamente, è consigliato usare i thread.

Per altro sia il numero di processi che il numero di threads dovrebbe essere limitato in tutti i SO (un po' di versioni fa in Linux non era così, tant'è che era soggetto a fork-bomb, potevi creare un numero elevato di processi, magari con un while infinito ed impallare il sistema :D ).

Tommo
25-02-2010, 23:10
Comunque, per una applicazione come una semplice chat in realtà mi sembrano eccessivi pure i threads :asd:
Mi sa che si fa meglio a fare proprio seriale?

bobbytre
25-02-2010, 23:13
Comunque, per una applicazione come una semplice chat in realtà mi sembrano eccessivi pure i threads :asd:
Mi sa che si fa meglio a fare proprio seriale?

per una semplice chat , almeno due th ci vogliono , uno che gestisce l'invio dei dati e uno che gestisce la ricezione.

Tommo
25-02-2010, 23:22
Boh credo che si possa fare anche senza, le chat esistono da ben prima dei processori dual core :D

bobbytre
25-02-2010, 23:25
Boh credo che si possa fare anche senza, le chat esistono da ben prima dei processori dual core :D

:mbe:

clockover
26-02-2010, 00:35
:mbe:
effettivamente non l'ho capita nemmeno io :D :D !

Comunque non devo fare una chat! Il mio progetto è un elenco telefonico remoto (ma può funzionare anche in locale)! Quindi non ho un numero ben preciso di client connessi! Comunque magari il mio prof (che tra l'altro è un qualcosa di disumano, un vero debugger umano) potrebbe avere una valutazione migliore nel vedere che sono stati usati i thread anzichè delle fork!

bobbytre
26-02-2010, 00:51
effettivamente non l'ho capita nemmeno io :D :D !

Comunque non devo fare una chat! Il mio progetto è un elenco telefonico remoto (ma può funzionare anche in locale)! Quindi non ho un numero ben preciso di client connessi! Comunque magari il mio prof (che tra l'altro è un qualcosa di disumano, un vero debugger umano) potrebbe avere una valutazione migliore nel vedere che sono stati usati i thread anzichè delle fork!

per remoto intendi che agisca come server , cioe' accetta delle connessioni fa la ricerca in un database e restituisca il valore trovato ?
In genere in questi casi si usano soluzioni multithread , in cui un il th principale è in ascolto, quando riceve una chiamata , questa viene gestita da un th separato mentre il principale si rimette in ascolto

WarDuck
26-02-2010, 01:03
Boh credo che si possa fare anche senza, le chat esistono da ben prima dei processori dual core :D

Non c'entra niente, è una questione di multi-tasking che si può fare anche su un processore single core e del resto è quello che s'è sempre fatto per poter far sembrare che le applicazioni girassero "contemporaneamente", ad esempio tramite una tecnica a divisione di quanti di tempo (in pratica ad ogni thread a turno viene assegnato un certo tempo di esecuzione da parte dello scheduler del SO).

Tommo
26-02-2010, 01:14
Non c'entra niente, è una questione di multi-tasking che si può fare anche su un processore single core e del resto è quello che s'è sempre fatto per poter far sembrare che le applicazioni girassero "contemporaneamente", ad esempio tramite una tecnica a divisione di quanti di tempo (in pratica ad ogni thread a turno viene assegnato un certo tempo di esecuzione da parte dello scheduler del SO).

Ok era la cavolata delle 23:00 :asd:

clockover
26-02-2010, 02:23
per remoto intendi che agisca come server , cioe' accetta delle connessioni fa la ricerca in un database e restituisca il valore trovato ?
In genere in questi casi si usano soluzioni multithread , in cui un il th principale è in ascolto, quando riceve una chiamata , questa viene gestita da un th separato mentre il principale si rimette in ascolto

Si esatto! Ovviamente devo progettare e scrivere sia il server che il client!

banryu79
26-02-2010, 10:29
In genere in questi casi si usano soluzioni multithread , in cui un il th principale è in ascolto, quando riceve una chiamata , questa viene gestita da un th separato mentre il principale si rimette in ascolto

Stai parlando di un thread pool?

clockover
26-02-2010, 14:48
Buttiamola così!

Volendo utilizzare i thread!

Non posso utilizzare una unica dichiarazione per tutti i thread di gestione vero?

ad esempio (molto molto approssimato come esempio)

pthread_t unico;
while(1){
socket_client = accept(socket_benvenuto, struttura, ecc......);
pthread_create(&unico, NULL, thread_di_gestione, (void*)&socket_client);
}

non so se sono stato chiaro

clockover
23-05-2010, 19:46
Allora raga riesumo il thread perchè mi è sorto un nuovo problema...

Ho deciso di reindirizzare lo stderr su un file di log... secondo me sta cosa al prof piace! Il problema principale è: se l'apertura/creazione del file di log fallisce, come mi devo comportare?
1) Devo terminare l'esecuzione del programma?
2) Gestire l'errore in modo che il file venga comunque creato?
3) Oppure continuare l'esecuzione e stampare a video i vari errori?
Avevo innanzitutto optato per quest'ultima opzione, ma la trovavo scomoda in quanto per scrivere su file utilizzavo un mutex, che non sarebbe più stato necessario in caso di stampa a video! Forse mi conviene più puntare sulla seconda...
Cosa ne pensate?

WarDuck
23-05-2010, 20:19
Allora raga riesumo il thread perchè mi è sorto un nuovo problema...

Ho deciso di reindirizzare lo stderr su un file di log... secondo me sta cosa al prof piace! Il problema principale è: se l'apertura/creazione del file di log fallisce, come mi devo comportare?
1) Devo terminare l'esecuzione del programma?
2) Gestire l'errore in modo che il file venga comunque creato?
3) Oppure continuare l'esecuzione e stampare a video i vari errori?
Avevo innanzitutto optato per quest'ultima opzione, ma la trovavo scomoda in quanto per scrivere su file utilizzavo un mutex, che non sarebbe più stato necessario in caso di stampa a video! Forse mi conviene più puntare sulla seconda...
Cosa ne pensate?

IMHO in quel caso potresti stampare l'errore a video ed usare la cartella temporanea /tmp per il file di log.

clockover
23-05-2010, 20:28
Quindi se mi fallisce l'apertura del mio file di log devo crearne un altro nella cartella /tmp e avvisare magari di questo evento a video....

clockover
24-05-2010, 11:45
Utilizzando un file di log in un server multithread devo per forza usare un semaforo mutex, altrimenti potrei avere due thread in concorrenza che scrivono sullo stesso canale... ad esempio

if(qualcosa == -1){
wait();
perror("Si è verificato un errore");
signal();
}

eventualmente continuo

o sbaglio?