Newsgroup: it.comp.os.linux.development
Titolo: Thread in C

Dov trovo delle info per creare dei thread in C?
Se ho un programma principale non mi conviene forkare il processo per
fargli eseguire solo un apicolla parte del codice, vero?
Grazie molte, ciao
Lumaca
lum...@writeme.com
ICQ: 12424362

fargli eseguire solo un apicolla parte del codice, vero?
Sotto Linux i threads sono normali processi che condividono
l'address space per cui la differenza e` solo nella forma,
sostanzialmente.
-- 
Lorenzo
"Given enough eyeballs, all bugs are shallow", Linus'Law
(per rispondere via email fai un rot13 dell'indirizzo)
(apply a rot13 to reply)

fargli eseguire solo un apicolla parte del codice, vero?
Dipende, probabilmente si.
-- 
ciao, | [Per rispondere togli "toglimi" dal mio indirizzo.]
Marco | * The Internet is full. Go away.  -- Joel Furr *
      | (Ri)scoprire fidonet: 
http://bbs.mi.linux.it

 Dov trovo delle info per creare dei thread in C?
Prova: 
http://pauillac.inria.fr/~xleroy/linuxthreads/
-- 
Cinereview: The Insider: grande prova di regia e interpreti. _/Davide\_
2 ore e 40, ma le vale tutte.  Voto: 8.5                     \Alberani/

 fargli eseguire solo un apicolla parte del codice, vero?
Dipende. Talvolta i threads creano piu` danni di quelli che risolvono, ma
talvolta sono utilissimi.
-- 
  /Kinkie
Se sulla scatola c'e` scritto "Per windows 95 e superiori", dovrebbe
funzionare sotto Linux, vero?

sostanzialmente.
mhaa io non mi convince, condividendo lo spazio di indirizzi
si ha un migliore sfruttamento della cache del processore,
in quanto dopo un context swich se il nuovo processo e nello
stesso spazio di indirizzi del precedente, non sara necessario
andare a prendere tutte le pagine in memoria,  perchè molte sono
sicuramente in cache. in ogni caso dipende
molto dallo stile di programmazione usato.
bye.


Grazie a tutti!
Addesso vedo un po' cosa fare...
Lumaca
Lumaca
lum...@writeme.com
ICQ: 12424362

andare a prendere tutte le pagine in memoria,  perchè molte sono
Non e` necessario nemmeno dopo un context switch tra processi.


Non e` necessario nemmeno dopo un context switch tra processi.
ma ne sei proprio sicuro?
eppure i processi girano in pagine di memoria fisica
diversa (almeno per quel che riguarda i dati)
mentre i thread condividono dati e codice.
altrimenti sta' storia dei thread è solo una stupidagine?

altrimenti sta' storia dei thread è solo una stupidagine?
Dipende da come vuoi usarli.


 Dipende da come vuoi usarli.
E qui sono con te.
Io ho usato i linuxthread solo per vedere come funzionano i thread e (debug a parte)
non me ne sono pentito.
Valentino

scelta: o ti fai una libreria dinamica, oppure devi linkare staticamente la routine
La memoria fisica viene condivisa anche dopo il fork.


nei due processi, ergo la routine viene allocata due volte.
non necessariamente, linux nel caso di librerie dinamiche
condivide il codice tra più processi, oltre che i dati in sola lettura,
quindi con una libreria dinamica il codice non viene comunque duplicato:-)
ciao.

 altrimenti sta' storia dei thread è solo una stupidagine?
I thread non hanno nulla a che vedere con la efficienza, specialmente sotto 
Linux dove i thread sono pochissimo diversi dai processi. Rappresentano
solo un approccio alternativo ad una classe di problemi che altrimenti
possono solitamente essere risolti facendo una programmazione orientata
agli eventi.
Insomma, sono una banale questione di stile di programmazione, niente di
piu`.


 wrote:


E' appunto quello che avevo detto io, o fai una libreria dinamica o il codice viene
duplicato...
Quello dei dati in sola lettura pero' non lo sapevo...
Se ho due processi A e B separati io pensavo che non potessero accedere una alla memoria
dell'altro se non con meccanismi di inter-process-communication tipo shared memory, code,
pipe, sockets ecc.
Poiche' conosco meglio altri OS e studio linux solo per diletto nelle poche ore libere
(notturne) dal lavoro e dalla famiglia, cerchero' sulla documentazione come si fa...
Valentino

 La memoria fisica viene condivisa anche dopo il fork.
Non lo sapevo proprio... studiero' meglio fork!
Valentino

 piu`.
Mah, mi sembra una descrizione alquanto riduttiva. Sembri dimenticare
che comunque i threads sono meno "pesanti" dei processi ed inoltre che
su macchine multiprocessore il threads vengono eseguiti da processori
divers (per quanto possibile).
Saluti,
Fabio Alemagna


In pratica e` condivisa in sola lettura e viene gestita con il
meccanismo copy-on-write.
Lo spazio d'indirizzamento dei due processi rimane comunque separato.


divers (per quanto possibile).
?? Anche i processi.


 ?? Anche i processi.
Ovvio, ma io rispondevo a Francesco il quale ha scritto che tra threads
e gestione ad eventi (quindi senza ne processi ne threads) c'č solo una
differenza concettuale.
Saluti,
Fabio Alemagna

dell'altro se non con meccanismi di inter-process-communication tipo shared memory, code,
Confondi lo spazio di indirizzamento logico del processo (unico per
ciascuno) con la memoria fisica (se necessario condivisa).


che comunque i threads sono meno "pesanti" dei processi ed inoltre che
A forza di ripetermi, a questo punto inizio a diventare offensivo...
*In* *linux*, i thread sono implementati allo stesso modo dei processi e
i secondi *NON* sono piu` lenti. Sono tutti e due veloci come i thread
di altri OS con peggiori prestazioni di context switch (es: solaris).


 Fabio Alemagna
Ehm, è permesso? Vorrei dire 2 parole...
In Linux (sugli altri Unix-like non metto becco...) l'implementazione
dei threads è
diversa nella libc5 e nella glibc2. Nella prima avevamo i pthreads
scritti negli States (mi pare al MIT) che usano fork e execve. Nella
glibc2 abbiamo i Linuxthreads, scritti da un bravo francese dell'INRIA
di cui purtroppo non ricorderò mai il nome, e che usano la sys_call
clone() (che se non sbaglio esiste dal kernel 2.0) anzichè fork.
Nella libc5 quindi non c'è vantaggio in termini di CPU load nell'usare i
threads anzichè semplicemente fork().
Nella glibc2, le 2 syscalls (anzi 3 con vfork() ) chiamano in realtà
sempre la funzione do_fork del kernel, ma ovviamente con diversi
parametri. Nello scheduling direi che non c'è nessuna differenza, e nel
carico sul sistema occorre tenere presente che fork lavora in
copy-on-write e quindi, almeno inizialmente è assai simile ad un cloning
( e viceversa clone() assomiglia a fork() nel fatto che i threads
differiscono per PID e PPID, cosa questa purtroppo non POSIX).
Direi allora che la glibc2 garantisce invece un minor carico di CPU con
i threads, ma non così accentuato grazie al copy-on-write di fork().
Probabilmente "la differenza" tra fork e clone non è tanto nel CPU load
quanto nelle applicazioni che se ne possono ricavare: concurrent I/O,
front - back ends con GUI, servers in generale (e altro) vengono più
eleganti, intuitivi, leggibili (~ belli) coi threads, e non è poco.
Naturalmente il rovescio della medaglia sta nel creare funzioni
rientranti, nel ricorrere a mutex... ma credo sia preferibile alle varie
forme di IPC, file locking...
Ho scritto troppo...
ciao, oops

clone() (che se non sbaglio esiste dal kernel 2.0) anzichè fork.
Proprio no, sia libc 5 che glibc 2.1 implementano l'API pthreads.
LinuxThreads e` una implementazione di pthreads (che effettivamente
usa clone(2) per creare veri kernel thread).
La vecchia libreria di thread in user space del MIT non poteva certo
usare fork, visto che questo non fornisce uno spazio di indirizzamento
condiviso.


 condiviso.
Per il fatto che entrambe implementino l'API certo che č cosě, forse mi
sono spiegato male...
Per la cosa importante invece, quando ho letto la tua osservazione mi
sono detto: ci sono cascato. La tua osservazione č giusta come 2+2=4.
Qundi, mogio mogio sono andato a rivedermi i sorgenti della libc5, e lě
ho visto che per gestire i threads fa direttamente delle malloc per
delle strutture, lo stack di processo, mentre i threads stanno su una
lista collegata. Quindi la differenza č che nelle libc5 tutto il lavoro
č eseguito in user space e fatto "a mano", nei LinuxThreads (glibc2) si
usa una syscall, con tutti i vantaggi che ne derivano.
I'm sorry, grazie di avermi corretto.
Ciao, oops.


si usa la tecnica del copy on write, una pagina di dati viene
effettivamente duplicata nel momento in cui uno de processi che
la usa vi effettua una scrittura, non c'č motivo di avere due pagine
dati identiche in memoria.


be, all'utente questo dettaglio non appare,
ma le pagine fisiche dei dati non scritti da nessuno dei processi forkati,
sono condivise, in spazi di indirizzi diversi però.
ciao.

 
Scusami ma non capisco cosa intendi dire (in questo thread, tanto per
stare in
tema). 
Puo' darsi che li abbia capiti male ma i thread non servono per
condividere strutture di dati nello stesso spazio di indirizzi? Per
questo non usi una fork, non usi padre e figlio, ma strutturi il
programma coi thread, usandoli dentro un unico "processo" che condivide
gli stessi indirizzi logici ed ottieni in automatico la condivisione dei
dati, al prezzo di dover usare i mutex e gli ammennicoli connessi.
Questa mi era parsa la loro utilita' (e da quel che dici mi pare
confermata), e da qui esce quel che non capisco e cioe' la tua critica
nei loro confronti. Mi e' invece assolutamente chiara l'altra questione
e' cioe' che in linux non e' assolutamente vero che sono piu' leggeri.
Ciao
-- 
Simone Piccardi
Microsoft is NOT the answer. Microsoft is the Question.
The answer is: "NO!"

condividere strutture di dati nello stesso spazio di indirizzi? Per
Si. Di solito la maggior parte dei programmi che usano thread non ne
hanno veramente bisogno, e potrebbero fare tutto molto piu`
efficientemente con una macchina a stati.


 divers (per quanto possibile).
Poi ci aggiungi la necessita` di serializzare gli accessi alle strutture
dati condivise (mutex, semafori, monitors, quello che preferisci) e
immediatamente i threads diventano molto meno attraenti se non per delle
classi di problemi molto ben delimitate.


 ?? Anche i processi.
Ma non un programma single-thread basato su select(2) o altri meccanismi di 
programmazione event-oriented.


 differenza concettuale.
Please rileggi. La differenza e` solo concettuale nella maggior parte dei
casi, ma non sempre: per esempio se devi fare un rendering su una macchina
multiprocessore il vantaggio di usare dei threads per parallelizzare il
lavoro e` evidente, ma se devi fare - per esempio - una applicazione X, la
differenza e` molto meno importante. Se devi fare un semplice webserver e`
molto meglio usare la programmazione orientata agli eventi.
Insomma, come sempre non esiste la "soluzione definitiva". Esiste una
soluzione migliore per una specifica applicazione.


Senza la pretesa di riferirmi a quello che hai detto in modo
particolare, vorrei comunque precisare che i threads, in linux, non sono
particolarmente idonei ad un'esecuzione su architetture multiprocessore,
e hanno, pur considerando esclusivamente il punto di vista del kernel,
per così dire, qualche differenza rispetto ai processi. Ma non mi piace
correggere i posts altrui perchè penso che inevitabilmente, mettendo per
iscritto, è facile esporsi a successive replies.
Il primo punto deriva dal fatto che i threads sono comunque implementati
all'interno di un task, e per sua natura il parallellismo su
architetture multiprocessore spesso si basa sul task. Infatti una
soluzione che permetta di implementare un effettivo parallellismo di
threads (e che è stata usata in implementazioni dei POSIX threads) e
quella di creare dei wrapper che nel creare dei threads creino in realtà
dei task (= processi) e li spediscano in esecuzione su questa o quella
cpu, "riempiendoli" per così dire di qualche threads.
L'altro punto, le differenze rispetto ai processi, è affine (almeno
nella mia esposizione): se abbiamo un blocking I/O su uno dei threads di
un processo, l' intero pool di task può bloccarsi. Quindi il kernel
evidentemente mantiene una struttura che permette di lavorare sui
threads collettivamente, e questo vuol dire che li gestisce diversamente
dai processi.
Non sono assolutamente in grado di spingermi più nel dettaglio
dell'implementazione in linux (almeno per ora :) ), non so molto più di
questo. Mi farebbe senz'altro piacere ricevere una reply che precisi
ulteriormente i dettagli l'implementazione in linux...
ciao ciao.

ulteriormente i dettagli l'implementazione in linux...
Saro` il piu` chiaro possibile: in linux, i processi sono thread che non
condividono nulla. I thread possono condividere un numero variabile di
cose (spazio di indirizzamento, privilegi di sicurezza, file descriptor,
segnali, eccetera). Non ci sono altre differenze.


 ulteriormente i dettagli l'implementazione in linux...
Vedi un mio post precedente.


Mi riferivo agli user-space threads esclusivamente.
Ripeto che non conosco così bene lo specifico dell'implementazione linux
dei threads, l'ho già detto prima, quello che ho scritto  viene
semplicemente da qui: (ah si: per Marco: 2 righe più sotto c'era la
(tasks = processi), non essere così precipitoso ;) )
User-Space Threads
...
Disadvantages. User-space threads have a problem that a single thread
can monopolize the 
	timeslice thus starving the other threads within the task.
	Also, it has no way of taking advantage of SMPs (Symmetric
MultiProcessor systems,
	e.g. dual-/quad-Pentiums). Lastly, when a thread becomes I/O blocked,
all other 
	threads within the task lose the timeslice as well.
Solutions/work arounds. Some user-thread libraries have addressed these
problems with
	several work-arounds. First timeslice monopolization can be
	controlled with an external monitor that uses its own clock tick.
	Second, some SMPs can support user-space multithreading by firing up
tasks
	on specified CPUs then starting the threads from there [this form of
SMP 
	threading seems tenuous, at best]. Third, some libraries solve the I/O
blocking
	problem with special wrappers over system calls, or the task can be
written for
	nonblocking I/O.
Spero che il minimo di impaginazione che ho fatto arrivi integra fino a
voi.
Ovviamente quelle cose non le ho scritte io ;) , sono semplicemente in:
Threads-FAQ/html/Types.html
che, come sicuramente Marco ci può confermare, sta in tutte le migliori
distribuzioni ;) del linux.
Ciao, 
P.S.: ah dimenticavo: così, tanto per discutere, senza incazz... ok?