Newsgroup: it.comp.lang.c
Titolo: multithread domanda generale

Salve.
Ho tante domande per voi.
Problema: ho un programma multithread in un sistema singolo processore, 
singolo core, singolo tutto (ARM9). Un thread cambia il valore di un int 
e gli altri thread lo leggono.
Domande:
1) Devo mettere un mutex "intorno" a questo int? 
2) C'è la possibilità che un thread legga l'int mentre l'altro lo sta 
scrivendo? 
3) La scrittura di un int non è atomica?
4) Se la precedente è falsa, c'è qualche assegnamento di tipo che sia 
atomico (short, etcetc) ?
5) Le risposte di cui sopra sono valide per tutti i SO? o cambia qualcosa 
con lin/win?
6) cambia qualcosa c o c++ ?
7) link? 
8) grazie!
Mario

6) cambia qualcosa c o c++ ?
No.

 3) La scrittura di un int non è atomica? 
mi autorispondo un po.
http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Atomic-Builtins.html
senza però essere convinto.

 
http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Atomic-Builtins.html
Scusate, ultima volta giuro!
Il tutto è nato da questo:
http://doc.trolltech.com/qq/qq14-threading.html#theatomicoperations
Qual'è la necessità di 
q_atomic_increment(x)
se l'incremento di un int non è atomico?



Perchè l'incremento è una operazione ben differente da una semplice 
lettura o semplice scrittura.
Quando leggi o scrivi un intero, l'operazione è atomica (se la 
piattaforma lo supporta), nel senso che il valore che vai a leggere è 
sempre in uno stato consistente.
Ad esempio, se un thread sta scrivendo un valore y in un registro il cui 
valore è x, allora un altro thread che accede lo stesso registro leggerà 
o x o y.
Nel caso di operazione di incremento, la cosa è più complessa.
Leggiti questi articoli dalla wikipedia:
http://en.wikipedia.org/wiki/Atomic_operation
http://en.wikipedia.org/wiki/Memory_barrier
Manlio Perillo

   
Su kernel, scheduling, un po' in generale sul multithreading:
http://qnx.com/developers/docs/6.3.2/neutrino/sys_arch/kernel.html
B.

 sempre in uno stato consistente.
Grazie!
tutti molto preziosi.
vado a studiare.
Mario

 Mario

 7) link?
Cerca su google multithreading, lock, semafori, mutex, ecc. ecc. ecc.

 che se viene interrotta sul più bello può succedere un popò).
Un popò? :|
E comunque... visto che si parla di un "singolo processore, singolo
core, singolo tutto", direi di staccare gli interrupt prima della
sezione critica e riattacarli dopo, tanto per non inserire quintali di
follie derivanti dalla programmazione ad alto livello per risolvere un
problema banale.

 problema banale.
A parte che non sempre, "mai" se si parla di Win2k/Xp/Vista/*nix, è
possibile mettere mani agli interrupt, ma comunque a prescindere dal
fatto che si tratti di singolo/multi processore, singolo/multicore, è
il fatto che il processore venga assegnato ad un thread prima e ad un
altro thread dopo a far sì che si possa incorrere in un problema tipo
l'interruzione di una sezione critica. E se ci sono strumenti appositi
(come mutex/semafori) si possono usare quelli in modo da staccarsi
dall'hardware.

 problema banale.
No, che si tratti di un solo processore o di due, di un solo core o di
due o più core, il discorso non cambia: gli interrupt (a meno di non
lavorare in ambienti un po' datati) non si possono toccare, è il
kernel ad occuparsene (e menomale, direi).
Ai programmatori non resta che l'uso di mutex/semafori per proteggere
le sezioni critiche.

 dall'hardware.
Non mi fraintendere: anche io opterei per questa scelta, anche solo
per aumentare la scalabilità del codice. Di certo però alla domanda
"la scrittura di un int è atomica?" non si può rispondere ipotizzando
un'applicazione in user space su un os Win/*nix.

 kernel ad occuparsene (e menomale, direi).
Ti svelo un segreto: c'è anche chi programma a livello di kernel.

   
Disabiltare gli interrupts va bene in mini-sistemi o applicazioni tipo
embedded(e anche qui potrebbe essere discutibile):
e' assolutamente da evitare se si dispone di altri meccanismi (mutex o 
altro).
E' una *follia* disabiltare gli interrupts quando se ne puo' fare a meno:
una cosa del gerere (se il sistema la rende possibile) puo' facilmente
causare l' hang-up del sistema.
B.

 causare l' hang-up del sistema.
Ad un buon programmatore (o anche ad uno cattivo) basta molto meno per
causare un hang-up. Ma anche solo per fargli mettere/togliere locks il
50% del tempo macchina invece che passare una decina di cicli di clock
a interrupts staccati. Ovviamente non è un meccanismo accettabile su
sistemi che non hanno memorizzazione degli INT ma, che io sappia,
ormai per trovarli occorre costruirseli a mano.
Anch'io (anche se non in questo caso) userei un semaforo. Dico
semplicemente che non è una buona idea uccidere mosche a cannonate.

 un'applicazione in user space su un os Win/*nix.
Beh perchè no?
Chi programma un software multithread ed ha una variabile globale "int
pippo", può giustamente chiedersi: pippo=10 è atomica? Se ho 27 thread
che la utilizzano, essendo una int, devo preoccuparmi di usare qualche
accorgimento per assegnarle valori oppure è atomica?
Il dubbio - quindi - può arrivare anche se NON si programma in kernel
space.

 semplicemente che non č una buona idea uccidere mosche a cannonate.
Paragone non appropriato. In un sistema complesso
la manipolazione diretta di interrupt(ammesso di poterlo fare)
e al solo scopo di proteggersi da concocorrenza, va lasciata
al SO e non va fatta quando esistono meccanismi adatti allo
scopo gia' previsti dal SO e presumibilmente portabili su altri
SO.
B.


Continui a mancare il punto. Magari il nostro Mario sta programmando
su una semplice scheda ARM, niente OS, niente librerie. Non mi sembra
una cosa strana o fuori dal mondo.
E comunque,  tanto per chiudere il discorso per quanto mi riguarda e
per rimanere sullo standard ISO: il C non sa niente di thread, mutex o
interrupts. Non esiste quindi una risposta relativa al C riguardo al
problema. Possiamo avere ciascuno la sua idea ma non esiste una
risposta "vera" a priori.
Magari il povero Mario l'abbiamo confuso più di quanto già non fosse
all'inizio.
P.S.
Riguardo le tue dissertazioni sui meccanismi di funzionamento degli OS
non ti ci sei nemmeno avvicinato.

   
Ma va ?
Ma va!
B.

 Ma va!
Su sistemi uni/multi-processore per questo tipo di operazioni a
livello kernel si usano gli spinlocks.