Newsgroup: it.comp.lang.c++
Titolo: quesito semplice

Se ho una Classe che implementi (ad esempio) una lista e il costruttore si
preoccupa di assegnare un numero sempre crescente a ogni oggetto inserito in
lista, posso essere sicuro che se più funzioni cercano di inserire un
oggetto in lista il numero assegnato non sia scambiato tra i vari oggetti?
molto grossolamanete questo sarebbe il codice di assegnamento del numero
class lista {
public:
    lista();
private:
    item_class oggetti;
    int id = 1;
}
lista::lista() {
    oggetti.pushback(id++);
    return(id - 1);
}
--
San Vegeta from Hell

 }
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

 wrote in message
flmu7.7345$0Y2.1...@news.infostrada.it...

uhm.... non ho ben capito quello che chiedi, ma credo che ciò che ti serve
sia un oggetto statico, ossia che abbia un tempo di vita globale.

Ha fatto più errori che righe di codice ;-)
--
______________________________________
Saluti dal Grande VEGETA PRINCIPE DEI SAIYAN
Il Millenium Bug ora si chiama WindowsME.... =(

 Ha fatto piů errori che righe di codice ;-)


 mente :)
Non esiste in C++ il concetto di thread e per tanto non puoi fare una classe
thread-safe.
Devi affidarti al sistema operativo su cui girera' il programma usando dei
meccanismi classici di sincronizzazione (monitor, semafori etc etc).
Ciao.
Gaetano.
-- 
Posted from 
dell-01.mm.eutelsat.org
 [194.214.173.17] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 mente :)
Assolutamente no. Due thread distinti li devi considerare a tutti gli effetti
del tutto indipendenti. Persino scrivere:
a++;
e' pericoloso se puo' essere eseguita da due thread concorrenti senza alcuna
sincronizzazione.
Quindi se stai lavorando con thread multipli devi per forza sincronizzare tutti
gli accessi a variabili visibili da entrambe. Usando, ovviamente, le primitive
di sincronizzazione che sono platform specific.


del tutto indipendenti. Persino scrivere:
Ma non sarebbe giusto aggiungere al C++ un supporto (anche semplice)
ai thread?
-- 
Marco Barisione (ICQ 84277092)
Su it.news.gruppi si sta discutendo della creazione di it.comp.lang
dove si parlerà dei linguaggi senza un proprio newsgroup e dei
confronti fra i diversi linguaggi.
Se sei interessato unisciti alla discussione.

 ai thread?
Sarebbe giusto aggiungere un supporto ai thread. Sarebbe giusto aggiungere un
supporto alle closure. Sarebbe giusto aggiungere un supporto alle espressioni
regolari. Sarebbe giusto aggiungere un supporto alle architetture parallele o
multiscalari (singolo thread con operazioni multiple eseguite
contemporaneamente). Sarebbe giusto aggiungere un supporto alle GUI. Sarebbe
giusto aggiungere un supporto alle socket o comunque al networking. Sarebbe
giusto aggiungere un supporto al binding dinamico. Sarebbe giusto aggiungere un
supporto ai metadati. Sarebbe giusto aggiungere un supporto decente
all'aritmetica floating point (che e' praticamente al livello del C89!!!).
Sarebbe giusto aggiungere alla libreria il supporto ai grafi e alle hash table.
Pero' nessuna di queste cose esiste. E d'altro canto quasi tutte (e altre
ancora) verranno prese in considerazione per la prossima versione dello
standard.
Come dice Papi: "l'asta e' aperta".


a parte il fatto che è sempre interessante leggere quello che scrivi, per
tutto ciò che sai, ora sono in lacrime pensando al fatto che devo persino
preoccuparmi della sincronizzazione per delle operazioni semplici solo
perchè eseguite concorrentemente...
grazie mille cmq
--
San Vegeta from Hell
"Andrea Ferro" <And...@UrkaDVD.it> ha scritto nel messaggio
news:jIGu7.62$b56....@nreader1.kpnqwest.net...


PRIMA di TUTTE le operazioni di inserimento richieste dal thread 2. 
L'unico modo di farlo e' sincronizzare i thread, solo che a
questo punto non mi spiego a cosa serva scegliere due strade
parallele (i thread), per poi serializzarle (l'uno di
seguito all'altro).
-- 
Andrea Laforgia - walkietalkie(at)
libero.it

Come dice Papi: "l'asta e' aperta".
Dio, un riferimento migliore no ?


ora sono in lacrime 
Non piangere.
Avrai tempo per piangere quando ti prendero' a bastonate per
il modo in cui quoti.  Per cortesia, quota *sotto* il testo
e riportando solo lo stretto necessario.
In quanto alle bastonate: scherzo ovviamente.


 perchè eseguite concorrentemente...
Invece a me fa sorridere che dici "solo" perche' eseguite concorrentemente. La
mia esperienza e' che quando non e' strettamente necessario e' sempre meglio
evitare l'esecuzione concorrente. Naturalmente nel caso di codice generico e
riutilizzabile (librerie) prevedere l'esecuzione concorrente puo' essere
obbligatorio. Pero' di solito basta preoccuparsi del problema della "reentrancy"
e lasciare all'applicazione i dettagli della sincronizzazione.
In ogni caso l'esecuzione concorrente e' una delle cose piu' complesse da
gestire in un SW che la supporta. L'uso dell'aggettivo "solo" quando si parla di
esecuzione concorrente fa veramente sorridere. Sarebbe come dire che devi
prestare attenzione a come ti muovi SOLO perche' stai scalando una parete di 6°
grado in free-climbing (ovvero senza chiodi e corde).


 Sarebbe giusto aggiungere un supporto al binding dinamico. 
Cosa intendi? Non ti bastano le funzioni virtuali o vorresti 
aggiungere membri al volo solo ad alcune istanze di classi ?
Ciao 
Gaetano.

 wrote in message
news:6177e1d7.01100...@posting.google.com...

Non intendevo certo dire che in C++ non esiste nessun supporto di nessun tipo al
binding dinamico. Mi sono espresso male ma di fatto intendevo supporto a cose
come il dynamic typing e il multiple dispatch.


 Andrea Ferro
Bhe, effettivamente io tendo a trascurare determinati aspetti che sono poi
importantissimi. Sto completando un demone FTP per un esame, non è niente di
così complicato, però è perfettamente plausibile che più utenti debbano
eseguire operazioni concorrentemente e quindi preoccuparmi di controllare le
esecuzioni quando si opera sugli stessi dati. Ciò che mi ha "abbattuto" è il
fatto che persino l'esecuzione di una funzione (nel mio caso il costruttore
di default di una classe) debba essere controllata dal programmatore.
Pensavo - probabilmente erroneamente - che ci fosse nel compilatore qualche
sorta di accorgimento per lasciare che termini l'esecuzione di una procedura
prima di farne partire un'altra.
Pensate al semplice problema di dover catalogare le operazioni effettuate da
un utente (o una specifica funzione, rimanendo nell'ambito di un programma):
bisogna per forza di cose controllare che la potenziale concorrenza con cui
verranno eseguite queste operazioni non rovini la corretta catalogazione. E'
più il lavoro per sincronizzare che non quello di catalogare, per cui stiamo
lavorando. E' frustrante doversi allontanare così dal problema principale.
scusate per la divagazione e il quote sballato :)
Bruno

 ha scritto nel messaggio
news:3bbc5a5...@news.tin.it...


anche qui mi sono espresso male, sorry.
Ho usato il termine thread perchè sto sviluppando un programma che girerà
sotto sistemi UNIX e pensavo all'esecuzione concorrente di operazioni da
parte degli utenti. Siccome diverse parti del programma operano sugli stessi
dati, io volevo esser sicuro che se una funzione richiede la creazione di un
oggetto (richiamando quindi il costruttore di una classe A) e un'altra
funzione richiede la stessa cosa prima che la precedente operazione sia
terminata, l'esecuzione di almeno tutte le operazioni del costruttore
fossero serializzate.
Uhm, il discorso è contorto, ma la mia scarsa preparazione in materia non mi
permette di spiegarmi meglio...
Abbiate pietà di me :)
Bruno

 esecuzioni quando si opera sugli stessi dati.
Il bello e' che se il tuo SW multithreaded gira su un server munito di una sola
CPU, alla fine diventa meno performante che non se lo avessi scritto
monothreaded.
Se il tuo demone FTP deve girare solo ed esclusivamente su server monoprocessore
ti conviene svilupparlo come thread unico. Se invece stai progettando un SW
scalabile e che quindi puo' essere configurato per lavorare su vari server
aventi caratteristiche differenti ha senso ed e' conveniente svilupparlo
multithreaded e, a seconda del design che stai sviluppando, permettere la
creazione di un numero di thread leggermente superiore al numero di processori
presenti. In questo caso TUTTO il design del tuo demone dovrebbe essere basato
sull'esecuzione concorrente minimizzando al massimo i punti di sincronizzazione.
Naturalmente il tutto e' fortemente platform dependent e pertanto vale la pena
di valutare le alternative che la piattaforma in questione ti offre sia come
sincronizzazione dei thread che come esecuzione di IO asincrono.


 fossero serializzate.
Comincio ad avere la sensazione che stai pensando di creare un thread per ogni
utente che si connette. Te lo sconsiglio vivamente. Un server FTP generalmente
e' in grado di gestire parecchi utenti contemporaneamente ma di rado ha piu' di
una manciata di processori. Gestire 50 utenti su una macchina biprocessore
creando 50 thread e' un mezzo suicidio sia in termini di risorse che in termini
di performance. Molto meglio limitarsi a cinque o sei thread al massimo (e sono
fin troppi).


creando 50 thread e' un mezzo suicidio
Anche perche' Windows, per esempio, ha un limite ufficioso
di 16 thread attivi e ne supporta malamente altri.



E infatti è proprio così. Come già detto non sono grankè ferrato in materia
(è pur sempre la prima volta che svolgo un progetto del genere), però
considerando che lo sviluppo in C++ mi sembrava una buona idea creare un
thread nuovo per ogni utente, permette di mantenere una visione abbastanza
astratta di ciò che può succedere... almeno era questa l'idea che mi ero
fatto...
Visto che siamo già abbondantemente OT, posso chiederti di illustrarmi
(magari via email per non allungare il discorso qui sul ng) la soluzione
alternativa che si potrebbe adottare pur mantenendo una visione astratta del
problema? La velocità è l'ultimo problema di cui devo occuparmi in questo
progetto, per cui andrebbe bene anche così com'è ora, però mi incuriosisce
il tuo suggerimento di limitarmi a 4 o 5 thread e ottenere lo stesso
effetto, io non ci avevo proprio pensato.
Bruno

 
Buon lavoro,
Fabio
 
 
-- 
Posted from 
flopiano.mm.eutelsat.org
 [194.214.173.28] 


 di 16 thread attivi e ne supporta malamente altri.
Thread per processo, ovviamente.
Pero' anche senza quel limite (per esempio in Unix) allocare decine o centinaia
di thread non ha molto senso dato che si possono fare le stesse cose con pochi
thread e in maniera piu' efficiente. E comunque anche ammesso che il tuo sia
l'unico programma che sta effettivamente usando la CPU, quanti thread pensi di
poter effettivamente eseguire in parallelo su un server con n CPU?
Certo, ci sono casi in cui e' molto piu' semplice bloccare un thread che gestire
la pacchettizzazione del lavoro da eseguire. Ma dovrebbe essere piu' l'eccezione
che non la regola. Per questo in genere (a seconda di dove e come sono fatti i
punti in cui il thread si blocca) conviene avere qualche thread extra rispetto
ai processori.


Thread per processo, ovviamente.
Ovvio.


 ad esempio)
Non so come funzioni ftpd. Ma un meccanismo che crea un processo per ogni
connessione di solito e' preferibile quando si vuole utilizzare la base utenti
di sistema per gestire la security. Ogni processo "gira" infatti sotto un
differente account di sistema ed e' limitato dal relativo accreditamento.
Dal punto di vista delle risorse e' una scelta ancora piu' pesante che non l'uso
di thread multipli. Ma dal punto di vista della sincronizzazione e' semplice: se
ciascun processo e' single threaded il problema non esiste (se non per accesso
concorrente ai file, ma questo vale per tutte le applicazioni).


 
Mi aggancio qui per dare soltanto una piccola dritta all'OP.
Gli sviluppatori di ACE (
http://www.cs.wustl.edu/~schmidt/ACE.html
) hanno
ideato (e implementato) diversi pattern per la programmazione di rete. Tra
questi, uno dei più importanti è quello che hanno denominato Reactor:
 
 
http://www.cs.wustl.edu/~schmidt/PDF/reactor-rules.pdf
Suggerisco all'OP (se anche non vuole studiarsi ACE, che in effetti è un
framework di una certa complessità) di darsi un'occhiata al documento
citato. Le tecniche illustrate non sono strettamente legate a specifiche
piattaforme, sebbene venga fatto riferimento a determinate API (ad es.
select() o WaitForMultipleObject()). Non è difficile, sfruttando quelle
idee, realizzare, ad esempio, un server in grado di gestire in un unico
thread di esecuzione più sessioni in modo concorrente.
Max


E' esattamente cosě. Per implementare un sistema di sicurezza semplice da
gestire ogni thread corrisponde a un utente e gira con i permessi accordati
all'utente. Cosě buona parte dei controlli d'accesso viene effettuato
direttamente dalle syscall e io devo preoccuparmi solo di verificare la
corretta esecuzione delle stesse.
Ora che ho ben presente l'alternativa dei pochi thread posso dire di aver
scelto il metodo piů "pesante" perchč piů semplice da implementare (la
prerogativa principale del progetto č la correttezza dell'implementazione).
Perň farň presente nella relazione i pregi e soprattutto i difetti di tale
scelta, presentando la soluzione alternativa, che ho scoperto solo grazie a
voi.
Grazie mille per l'aiuto
Bruno

 all'utente.
Tieni conto anche del fatto che se un thread dovesse "morire" per qualche
motivo, si porterebbe dietro tutti gli altri......
Ciao
Gaetano.
-- 
Posted from 
dell-01.mm.eutelsat.org
 [194.214.173.17] 


 motivo, si porterebbe dietro tutti gli altri......
Per questo dicevo che quando si cerca di affrontare il problema della stabilità
quello della sincronizzazione e quello degli utenti multipli fregandosene delle
risorse, di solito non si usa neppure il multithreading ma addirittura il
multiprocessing.


 multiprocessing.
Considerando anche il fatto che in termini di prestazioni ( non di
occupazione di memoria )
oggi una fork(......) non e' poi cosi' tanto pesante copiando il working set
solo quando
c'e' effettivamente bisogno (modifica).


 ha scritto nel messaggio
news:002901c14da8$82b614e0$58bbfea9@gmendola...

Perchč dovrebbe portarsi dietro tutti gli altri?
Se č un processo figlio dell'unico thread preposto alla creazione degli
altri, se termina un figlio gli altri continuano ad esistere... Se termina
anomalamente il padre allora si che ci sarebbero problemi... E' questo che
intendevi?
Bruno

 intendevi?
No non e' cosě. E stai facendo confusione fra processi e thread e fra
terminazione normale e terminazione anomala.
Se un thread, qualunque esso sia, termina in maniera anomala (GP fault o
uncatched exception) tutto il processo termina e quindi anche tutti i thread di
quel processo.
Se un thread termina normalmente il processo termina quando sono terminati tutti
i thread (su alcuni OS potrebbe anche terminare quando esce il thread con cui e'
partito il processo, ma non e' questo che e' previsto dal paradigma
multithreading, non credo che sia quello che succede in unix e non e' quello che
succede in windows).


 Perchè dovrebbe portarsi dietro tutti gli altri?
Perche' il processo e' uno e se il sistema operativo termina un thread
perche' ha fatto qualche cosa di anomalo (ha acceduto alla memoria di un
altro processo ad esempio) questo lo fa mandando un signal al PID del
processo,
e morendo il padre muoiono anche gli altri thread.


 via Mailgate.ORG Server - 
http://www.Mailgate.ORG
Vabbè, ma a questo punto non si deve pensare che è un'eventualità
"disastrosa"?
E' come se l'applicazione stessa venisse brutalmente terminata perchè non in
grado di gestire una certa situazione, solo che lo fa il SO invece che
l'applicazione stessa.
Bruno

 l'applicazione stessa.
Disastrosa! Diciamo errore di programmazione, in uno dei miei ultimi lavori
si lavorava ad un servere per la gestione di transazioni (vendite, pagamenti
ed annulli
etc etc). Tutto era fatto multiprocesso invece che multithread, capitava a
volte (a
causa del fatto che le richieste di modifica dovevano essere implementate e
messe in
campo subito) di fare errori per cui un processo moriva e si bloccava solo
la funzionalita' che gestiva
il tempo di guardare i log per vedere cosa era successo, ricompilare
cambiare le librerie and go....
Se tutto fosse stato multithread invece che multiprocesso si sarebbe
bloccato il tutto.
Purtroppo non sempre il ciclo di produzione del software e' quello classico:
Specifiche --> Design --> Implementazione --> Test e spesso delle volte
nel mondo del lavoro i programmi devono essere pronti per ieri
(tranne in compagnie mastodontiche in cui la situazione e' completamente
l'opposto e perdono clienti ogni anno grazie alla dinamicita' di quelle
piccole).
