Multitasking e thread safe

di il
9 risposte

Multitasking e thread safe

Salve,
volevo porre una domanda a voi esperti, dato che non ho trovato niente in rete riguardante la questione. Da quanto ho capito, una funzione è thread safe se l'accesso a eventuali risorse condivise da più thread è regolato da meccanismi di lock (come per esempio i semafori). Se la funzione printf() non è thread safe, per esempio, è perché il buffer usato da printf() è condiviso fra le varie printf() dei vari thread, quindi una versione thread safe della funzione implementerebbe al suo interno dei semafori che rendono atomica l'operazione di scrittura sul buffer, in modo che un'altra printf() di un altro thread potrà usare il buffer solo dopo che la prima l'ha "rilasciato". Supponendo di aver capito bene, la mia domanda è questa: il problema è estendibile al multitasking? Nel senso: due printf() di due task (processi, non thread) diversi, condividono il buffer?

Grazie!

9 Risposte

  • Re: Multitasking e thread safe

    Per semplificare molto (anzi troppo, ma è solo per amore di sintesi) possiamo dire che le risorse (per esempio la memoria) sono condivise tra i thread mentre sono allocate logicamente in modo diverso per i processi in modo tale che ogni processo abbia la percezione che tutte le risorse siano a sua completa disposizione. Quindi il problema del thread safe non si pone per i processi, dato che non hanno risorse condivise. Però è sicuramente possibile fare danni di corruzione della memoria o inconsistenza del dato anche lavorando con i soli processi. I problemi della programmazione concorrente sono precedenti all'introduzione del concetto ti thread, quindi sono sicuramente possibili anche in assenza di multithreading.

    Quindi se in modo ortodosso, con multitasking intenti la capacità del sistema operativo di eseguire contemporaneamente più processi (e non thread) la risposta è: non è affetto da problemi relativi alla thread safety ma è sicuramente affetto da generici problemi relativi alla programmazione concorrente.
  • Re: Multitasking e thread safe

    Grazie mille! E' proprio quello che volevo sapere!
  • Re: Multitasking e thread safe

    A proposito dell'esempio di cui parlavo nel primo post, leggo testualmente su gapil: <<il codice della funzione printf starà su una sola pagina di memoria reale che farà da supporto a tutte le pagine di memoria virtuale di tutti i processi che hanno detta funzione nel loro codice>>. Allora mi pongo la domanda: ma se la funzione printf è una per i vari processi (tutti i processi in esecuzione, quando chiamano la printf, chiamano la stessa parte di codice), come fa la printf stessa a distinguere il processo da cui è stata chiamata e quindi creare un buffer di uscita relativo solo a quel processo? E poi: quello che c'è scritto su gapil vale solo se la libreria stdio (cioè la libc) è dinamica con una sola istanza in esecuzione o anche se è statica? E ancora: se vale solo nel caso che libc sia dinamica, il problema che mi sono posto nella prima domanda non è estendibile a tutte le funzioni appartenenti a librerie dinamiche?

    Grazie
  • Re: Multitasking e thread safe

    Consiglio: si studia sui libri, scritti da gente che lo fa per mestiere, NON SUI FORUM o sui pseudocorsi ONLINE !!!!!!!

    La frase che hai indicato:

    il codice della funzione printf starà su una sola pagina di memoria reale che farà da supporto a tutte le pagine di memoria virtuale di tutti i processi che hanno detta funzione nel loro codice

    e' incomprensibile pure per chi fa il programmatore di mestiere da 20 anni!

    La faccio breve, perche' per rispondere dovrei scrivere l'equivalente di diversi capitoli diun libro!

    Non voglio andare nei dettagli della terminologia Linux, ma ora uso itermini cosi' come vengono utilizzati in qualunque testo di teoria dei sistemi operativi:

    1) processi e thread sono oggetti concettualmente distinti

    1.1) i processi sono gestiti dal sistema operativo, due processi non comunicano tra di loro direttamente, ma solo attraverso dei meccanismi di interprocess comunication, una cosa simile alla comunicazione via rete (se non addirittura esattamente quella)
    Ogni processo ha la sua memoria, i suoi thread, e puo' accedere alle risorse del S.O. solo chiedendole a quest'ultimo, il quale controlla che non vengano usate male da piu' rocessi contemporanemanete. Tra l'altro, ogni processo ha il suo codice, il suo stack, ecc.
    Per quanto riguarda le librerie dinamiche, vedremmo dopo

    1.2) i threa vivono all'interno di un processo. Un thread di esecuzione e' una funzione che viene mandata in esecuzione in parallelo all'esecuzione del programma in cui il thread e' stato creato.
    Ogni thread ha un proprio stack, ma condivide la memoria e le variabili globali con tutti i thread del processo. Ovviamente ogni processo deve avere almeno un thread.
    Inoltre i thread eseguno il codice associato al processo. Quindi thread distinti possono eseguire lo stesso identico codice (ricorda che ogni thread ha un suo stack)

    Librerie statiche
    -----------------------
    Una libreria statica e' un insieme di funzioni salvate su file e che vengono caricate dal processo quando questo parte.
    Se due processi usano la stessa libreria, ogn'uno carica la sua copia.

    Librerie dinamiche
    --------------------------
    Una libreria dinamica e' come una libreria statica, solo che il sistema operativo si assicura che il codice venga caricato in memoria una sola volta.
    Ma ovviamente, anche se il codice e' stato caricato una sola volta, le variabili globali definite all'interno della librerai devono NECCESSARIAMENTE essere associate ad ogni processo, se no sai che disastro!

    Quindi
    ---------

    Come fa una funzione a sapere a che processo appartiene?
    Semplice: perche' viene eseguita da un thread che appartiene a quel processo.
    Inoltre, se utilizza delle variabili statiche inizializzate, queste sono state inizializzate specificatamente da quel processo (come dicevo, ogni processo ha la sua copia delle variabili globali).

    Applicazione->Libreria->Sistema Operativo
    --------------------------------------------------------------
    Come fa tutto l'ambaradan a funzionare senza casini?

    Concettualmente il sistema e' semplice: partizionamento.

    1) il sistema operativo mette a disposizione le primitive per accedere alle risorse globali (memoria, filesystem, tastiera, monitor, ...) e si assicura di coordinare le richieste da parte dei vari processi

    2) la libreria usa le primitive per accedere alle risorse globali, e si assicura di coordinare le rihieste da parte di piu' thread. Se non lo facesse, sai che disastro

    3) l'applicazione usa la libreria. E se l'applicazione e' multithreading, chi scrive il codice deve assicurarsi che la funzione di libreria che andra ad utilizzare sia thread-safe. Se non lo e', deve implementare i meccanismi di controllo della concorrenza necessari.

    Non tutto e' threads safe
    ------------------------------------
    Assicurare il controllo della concorrenza e' un'operazione estremamente pesante e che serve molto raramente. Per cui, in generale, si preferisce un'implementazione efficiente da un'implementazione thread-safe.

    E' ovvio che certe funzionalita' DEVONO NECCESSARIAMENTE essere thread-safe.
    I casi piu' banali sono, ovviamente:

    1) la creazione di threa
    2) l'allocazione della memora
    3) la scrittura su standard output

    Concludendo
    -------------------
    STUDIA SUI LIBRI

    E', ovviamente, questa e' una spiegazione spannometrica.
    Per capirne di piu', bisogna studiare sui libri
  • Re: Multitasking e thread safe

    Grazie per la pazienza, ma, scusa una cosa, Gapil non è un libro? Dicono che sia il migliore per la programmazione in Linux! Poi non lo so... può essere che dica un sacco di fregnacce... Sicuramente quello che dici tu è giusto, e infatti la mia curiosità è quella di riuscire a capire come i concetti che esprimi coesistano con la tanto criticata frase "il codice della funzione printf starà su una sola pagina di memoria reale che farà da supporto a tutte le pagine di memoria virtuale di tutti i processi che hanno detta funzione nel loro codice". A questo punto non riesco a capire cosa significhi questa frase, e la cosa non mi consola, dato che è su un libro (diciamo una guida) che molti programmatori Linux ritengono molto affidabile.
  • Re: Multitasking e thread safe



    Cosi' come e' scritta, quella frase non la capisco nemmeno io !!!!

    ...
    Ora l'ho capita!

    Per spiegarla bisogna andare nei dettagli dell'implementazione della memoria virtuale, del working set, dell'indirizzamento di memoria, della segmentazione della memoria, della paginazione, di come la memoria fisica viene usata nell'implementazione della memoria virtuale.
  • Re: Multitasking e thread safe

    La frase è giusta e semplice da capire, la funzione di una libreria si cerca sempre di caricarla una volta sola nel sistema operativo,i vari programmi ce la chiamano accederanno direttamente in quell'area di memoria ed eseguiranno il codice.
    Qui non serve il sincronizzare il buffer perche non è dichiarato statico nella funzione printf ma verrà allocato un nuovo buffer per ogni processo ma non per ogni thread che con qualche test noterai le differenze.
  • Re: Multitasking e thread safe

    vbextreme ha scritto:


    La frase è giusta e semplice da capire, la funzione di una libreria si cerca sempre di caricarla una volta sola nel sistema operativo
    E se la libreria è statica?
  • Re: Multitasking e thread safe

    Se la libreria è statica è come se fosse parte del programma quindi la stessa funzione sarà ricaricata tante volte quanti i processi lanciati.
    Quando linki una statica unisco il file .a al l'eseguibile mentre con le dinamiche devi interagire col s.o. in modo che ti metta a disposizione le funzioni che ti servono.
Devi accedere o registrarti per scrivere nel forum
9 risposte