Newsgroup: it.comp.programmare
Titolo: Re: Ancora multithreading: accesso concorrente a files binari

 2) Se devo mutexare il file 
"Usare un mutex" è decisamente meglio di "mutexare". Se lasci che sia
un solo thread a ricevere notifiche di lettura/scrittura dagli altri
thread, allora il mutex è necessario solo se un gruppo di notifiche
(vedi questo gruppo come una transazione) deve operare in maniera
atomica.

 [...]
Saluti  Manlio Perillo

scrivere e poi sbloccare.
Dipende da quali funzioni adoperi per la scrittura, perché potrebbe
darsi che non siano thread-safe. Io lascerei, per sicurezza, ad un
unico thread il compito di scrivere su file e taglierei la testa al
toro.

Archeopteryx ha scritto:
[cut]
scusate se ci ho dato dentro di brutto con le forbici; volevo 
agganciarmi alla discussione di Archeopteryx (un nome più semplice no 
è?! :D) rispetto anche al suo post precedente.
Il mio dubbio è questo:
In che modo vengono schedulati i pthread?
O più precisamente... per quanto ne so io, il sistema operativo non 
"vede i pthread" ma solo il processo a cui fanno capo e schedula quello 
per l'utilizzo delle risorse. Corretto?
Se così è, non è sufficiente utilizzare pthread per sfruttare i sistemi 
multiprocessore perchè in questo caso la schedulazione dei pthread 
avviene a valle di quella fatta dal SO sul processo a cui essi fanno capo.
Ovviamente le cose possono essere molto variabili in relazione al tipo 
di SO. Se sono implementati thread a livello di nucleo c'è da aspettarsi 
che la libreria pthread tenga conto di questo fatto e lo sfrutti di 
conseguenza.
Vi pare che il discorso fili?
Purtroppo non ho ancora un multicore, per cui non posso fare esperimenti 
chiarificatori.
Grazie
Giuseppe

"vede i pthread" ma solo il processo a cui fanno capo
Il sistema operativo schedula i thread.

 
Dovrebbe funzionare.
Ciao  Manlio

 [...]
Ciao  Manlio

Manlio Perillo ha scritto:

Si, proprio a quello facevo riferimento.
Supponiamo per esempio Linux che ha (a meno di kernel particolari che io 
sappia) un modello 1:1, secondo il mio modello mentale due pthread non 
potrebbero essere schedulati in parallelo su due processori perchè per 
il SO i thread non esistono. O no?
In effetti mi rendo conto che, anche qui, dipende...
può sempre essere che per ogni pthread venga generato un processo, ma a 
sto punto diventano solo un'interfaccia. O no?
I dubbi di un novellino!
Grazie
Giuseppe

il SO i thread non esistono. O no?
Scusa ma che intendi con "per il SO i thread non esistono"? 
Per il sistema operativo esistono SOLO i thread. Un processo
single-thread consiste, appunto, in un solo thread.

 
No, rileggiti meglio l'articolo della wikipedia e quelli collegati per 
capire la differenza tra thread e processo.
E per aumentare la confusione:
http://linux.die.net/man/2/clone
Ciao  Manlio

Andrea Laforgia ha scritto:

Ragionando in ambito linux
pthread è una libreria utente, il kernel gestisce solo processi.
In effetti questa faccenda mi è sempre rimasta un pò oscura... 
approfitto per chiarire.

pthread è una libreria utente, il kernel gestisce solo processi.
No, Linux gestisce processi e thread.

 
eh sono un pò arruginito ma a quello c'arrivo... la confusione forse mi 
viene proprio da qualche manpage, a quanto so, correggetemi se sbaglio, 
linux non implementa thread come entità separate ma solo come processi 
allegeriti, per questo tendo a confonderli un pò anche rendendomi ben 
conto che, teoricamente, sono cose differenti.
In ogni caso rileggerò.
grazie della pazienza... a volte rispondo troppo frettolosamente
Giuseppe

Andrea Laforgia ha scritto:

Se quella dei pthread in ambito linux è una libreria utente, il kernel 
non pò mica conoscere un pthread?!
Sempre che io sappia... linux non implementa i thread ma ha solo la 
possibilità di creare sottoprocessi allegeriti più o meno a piacimento.
Sto rispondendo a memoria... magari rivedo un pò meglio su qualche testo.
Ciao

non pò mica conoscere un pthread?!
Che significa "conoscere un pthread"? Non esiste un "pthread". La
libreria serve a mappare il concetto di thread sul thread "fisico"
implementato dal sistema operativo. Sotto Linux esistono sia i
kernel-space che gli user-space threads.

linux non implementa thread come entità separate
Che intendi per "entità separata"?

 
C'e' un poco di confusione tra "processi" thread e posix ;-)
Effettivamente originariamente non c'era distinzione tra processi
o task o thread ma col tempo si e' stabilita una distinzione tra
processo e thread.
Per processo si intende una applicazione costituita da dati e codice
che gira in un segmento di memoria protetto in hardware dalla MMU.
Il codice eseguito all' interno del processo, se gestito da un SO, 
costituisce un thread (o task) che puo' essere schedulato, insieme
ad altri ed il tutto costituisce un bel sistema multiprocessing.
L' implementazione tradizionale di Unix (e le versioni di Linux
fino a 2.5) segue questo modello.
per attivare un altro processo da codice in *nix si utilizza la
"fork", che appunto aggiunge un nuovo processo indipendente al
sistema (dati e UN SINGOLO thread).
Poiche' ogni processo ha un suo spazio di memoria dedicato, ogni
volta che se ne crea uno nuovo, va creato un nuovo spazio dati
in cui vanno anche ricopiati i dati del processo padre ed eventualmente 
vanno duplicati anche gli handle degli oggetti di sistema in uso.
Questa operazione e' molto onerosa e richiede molte operazioni
da parte del kernel.
Un altro approccio storico, seguito da molti sistemi real-time,
e' quello di evitare le complicazioni della gestione di spazi di
memoria indipendenti e protetti e gestire tutta la memoria
in modo flat: in questa architettura non ci sono processi,
ma solo threads (o task) ovvero pezzi di codice che possono
girare in modo concorrente tra loro e controllati dallo scheduler.
In queste architetture si implementa il multi-threading, in cui
codice e dati sono condivisi da tutti i thread (o task) e sono
caratterizzate da avere prestazioni globali molto migliori
rispetto ad un sistema multiprocessing, pero' a scapito di
sicurezza e stabilita'.
I sistemi moderni, da un certo punto in poi,hanno semplicemente
aggiunto la possibilita' di gestire piu' thread nello stesso
processo,che originariamente conteneneva solo un singolo thread,
gestiti allo stesso modo dei sistemi real-time.
La creazione di un thread in questo caso non comporta la duplicazione
di dati ne' quella di handle di sistema.
Poiche' un thread vive in un processo, ne condivide la stessa memoria
con tutti gli altri e questo espone il processo a problemi di sicurezza
e stabilita' ma ne aumenta di molto le prestazioni in temini di elocita' 
e consumo di risorse.
(Pero' se un processo si pianta, il sistema in genere no, perche'
comunque i guai sono arginati dalla protezione offerta dalla MMU,
il che rende i sistemi multiprocessing/multithreading piu' sicuri di 
quelli semplicemente multithreads).
Il modello Posix invece e' una interfaccia standard con cui e'
possibile creare applicazioni multithreading portabili su sistemi
diversi che offono una libreria Posix.
La librearia in genere, se il sistema non e' stato progettato come 
Posix, fa un wrap delle chiamate native del sistema host sulle
API standard POSIX: pero' le API native sono sempre disponibili!
Windows per esempio non e' un sistema Posix e per usare applicazioni
posix necessita di una libreria ad oc per mappare le funzioni native.
B.

Andrea Laforgia ha scritto:

uhmmmm abusavo un pò del linguaggio... pthread = thread mappato dalla 
libreria pthread.
Penso che brixrix abbia scovato il mio problema... kernel vecchio.
Qual'è la syscall per la creazione di un thread, l'equivalente di fork 
praticamente

 
Mi sa mi sa che abbiamo scovato il mio problema...kernel vecchio nei 
riferimenti teorici

 Che intendi per "entità separata"?
Beh a quanto pare la mia conoscenza era limitata al kernel 2.4 comunque...
(cit)
Il nucleo di LINUX affronta le differenze tra thread e processi in 
maniera molto semplice: adotta esattamente la stessa rappresentazione 
interna per entrambi. Un thread è solo un nuovo processo che condivide 
lo stesso spazio di indirizzi del genitore [...]
però si fa riferimento ad un kernel vecchio...2.2 addirittura.



pthread_create non è detto debba essere una syscall.
Su Linux i threads sono creati con la syscall clone, che è una 
generalizzazione di fork, in quanto permette di decidere se e cosa del 
contesto di esecuzione del "processo" figlio debba essere condiviso con 
il processo padre.
Dalla man page:
The main use of clone() is to implement threads: multiple threads of 
control in a program that run concurrently in a shared memory space.
Ciao  Manlio

 che fo? :)
Perche' polling? Scrivi un server per la scrittura dati
sospeso su una coda di messaggi:
tutti i client semplicemente accodano le richieste e
l' accodamento sveglia il server.
Finche' non ci sono richieste il server e' appeso
e non gira per nulla.
Usa un qualsiasi meccanismo IPC a disposizione o
ll limite puoi usare un socket cosi' i client posono
anche essere su machine remote, oltre che residenti
sullo stesso host (basta connettersi al localhost).
B.

e ho chiamato polling il tutto impropriamente.
E' un tipico problema producer/consumer. Il thread consumer (ovvero
quello che nel tuo caso gestisce il file) non deve fare polling, ma
attendere che gli venga notificata la presenza di informazioni nella
coda dai thread producer. Questa "attesa" non deve essere ovviamente
essere una "busy wait", ma su un oggetto di sincronizzazione.

 cambiando in meglio :) Insomma, sono parecchio indeciso.
Posix e' uno standard, ma l' implementazione di Win, che io
sappia,e' un poco poverella (pero' potrebbe essere migliorata),
in ogni caso, permette di avere applicazioni quantomeno
portabili, di certo piu' che applicazioni scritte con funzioni
native presenti solo in Win o Linux.
Io ti consiglierei di rimanere su Posix o utilizzare
dei socket, se vuoi scrivere una applicazione facile
da migrare su sistemi diversi (anche non-Linux, non-Win):
l' unica discriminante sarebbe la performance di un
meccanismo IPC basato su soket piuttosto di uno di altro
tipo: per comunicazione locale credo non ci sia molta
differenza, specie se l'operazione da eseguire da parte
del server e' temporalmente piu' lunga rispetto alla
comunicazione.
In alternativa wrappi le funzioni native del sistema
host in un modulo/classi separate, in modo da modificare
eventualmente solo questa parte dell' applicazione quando
la migri su un' altra piattaforma.
B.


Se usi C++, vedi anche:
http://matthias.vallentin.cc/2008/04/a-thread-safe-queue-based-on-boost-
thread/
Ciao   Manlio