Google+ Quarta Info B: 2013

domenica 12 maggio 2013

FILESYSTEM INODE

Un inode, solitamente utilizzato nei filesystem Unix, non è altro che una struttura di dati.
I filesystem inode (index node) consentono di creare dei blocchi con funzioni particolari sul disco, i quali gruppi di questi blocchi formano gli inode. Con questi filesystem, ogni file avrà un inode associato, con questo metodo però si rischia che i file superino il numero di inode disponibili. Nella directory radice (/) sarà presente una lista dove troveremo i riferimenti agli inode, che a loro volta punteranno a un file specifico.



Ogni inode è una serie di bit, che devono essere suddivisi per essere spartiti ad ogni informazione associata al file:

Un inode stesso può essere una struttura di inode, cioè può contenere dei riferimenti ad altri inode di livello più basso. Per capire meglio osserviamo questo schema:

Come si può notare con questo metodo, si riesce ad ovviare al problema di avere dei file troppo grandi  e un numero troppo basso di inode, creando appunto vari riferimenti e collegamenti fra gli inode.
Proviamo a fare un esercizio per capirne ancora meglio il meccanismo:

Indirezione tra gli inode:
L'inode che contiene elementi di una directory, verrà chiamato di livello -1. Chiameremo di livello -2 un inode con informazioni di una cartella che a sua volta punta ad un inode di livello -1. Ed infine di livello 0 l'inode che verrà puntato dagli inode di livello -1, proprio come una gerarchia a più livelli.s

FILESYSTEM FAT

Il filesystem FAT è uno dei primi della storia, venne utilizzato dalle prime versioni di winzozz da zio Bill. Questo si appoggia su una tabella apposita denominata FAT che contiene le informazioni che riguardano i file presenti su disco  ed i loro settori.
La FAT è la tabella dove troviamo le informazioni su quali settori sono allocati e a chi sono assegnati. Quando un elemento della FAT (File Allocation Table) punta a se stesso significa che quello è l'ultimo elemento della tabelle; questo ricorda molto il principio che sta alla base delle liste concatenata nelle quali troviamo però come ultimo elemento il NULL(cioè vuoto). Quando invece troviamo un elemento non nullo nella FAT, significa che il settore successivo sarà quell'elemento stesso. Oltre alla FAT, in questo tipo di filesystem è necessario conoscere anche la directory radice (/), la quale contiene tutti i file e il percorso associato. Inoltre è necessario sapere se il file preso in considerazione è veramente un file oppure una directory.
Quando viene creato un filesystem FAT, la prima partizione viene dedicata alla omonima tabella, una seconda serve per contenere la directory radice (/) (solitamente di qualche KB) e la terza partizione verrà invece utilizzata come spazio libero disponibile per l'allocazione dei vari file.

martedì 7 maggio 2013

I FILESYSTEM

Un filesystem deve far poter gestire al sistema operativo i vari file, ordinarli, rinominarli, assegnarli i permessi ecc. I file vengono utilizzati per archiviare istruzioni e informazioni(dati). Questi vengono archiviati in modo permanente, per poi poter essere riletti in un secondo momento. Un file può essere qualsiasi cosa, nella visione di Unix ogni cosa viene vista come un file, anche le stesse directory. Un file viene visto in generale come un insieme di blocchi di una partizione e naturalmente devono risiedere sul disco.
Esistono anche alcuni tipi di file, detti file speciali o di dispositivo, che non sono memorizzati in blocchi su disco, ma servono solamente per virtualizzare l'accesso a una periferica.
Nei file è presente un "Magic Number" (3 is a magic number :D ), che viene assegnato, solamente quando quel file è eseguibile o se appartiene ad una categoria di file, ad esempio file immagine o video. Una volta mandato in esecuzione quel file, il sistema operativo controlla che il Magic Number sia coincidente, se lo è allora verrà mandato in esecuzione (sempre che naturalmente abbia il flag X attivo).

Le chiamate a sistema e i servizi che il sistema operativo mette a disposizione dell'utente sono:
-Apertura
-Chiusura
-Lettura
-Scrittura
-Spostamento ( fseek() )
Un sistema operativo ha dei limiti sul numero di file che può aprire contemporaneamente, altrimenti si rischia di perderne i dati. È necessario che ci sia un protocollo che metta in comunicazione il file con il processo (l'utente). Naturalmente quando un file viene aperto in scrittura un altro processo non potrà aprirlo in lettura, tanto meno in scrittura; anche se alcuni sistemi operativi, non sono così rigidi e consentono che avvenga.
Per identificare un determinato utente, gli si associa un UID (user identifier) e per un gruppo un GID (group identifier). Questi (UID & GID) sono solomente dei numeri interi che ricordano molto PID, utili appunto per distinguere tra loro due cose dello stesso tipo.

Informazioni di un File:

lunedì 6 maggio 2013

I PROMESSI SPOSI (Pag. 753)

Le ragioni per cui Alessandro Manzoni decide si scrivere il romanzo "I Promessi Sposi" sono di renderla un'opera per un largo pubblico, desiderio di raccontare la storia delle persone comuni che rispetto ai grandi personaggi, non hanno mai lasciato un ricordo vivo dopo la loro morte.
Manzoni iniziò a scrivere questo romanzo nel 1821, a seguire ne finisce la prima edizione nel 1823, chiamata "Fermo e Lucia" che non verrà mai pubblicata. Insoddisfatto decide di riscriverlo e nel 1827 pubblica la prima effettiva edizione intitolata appunto "I Promessi Sposi", nella quale effettua anche una revisione linguistica adottando il fiorentino, oltre, che ad una revisione dei contenuti.(Pag. 759 - 1°capoverso)
Nel 1840 pubblica la versione definitiva, nella quale si nota una conferma dell'utilizzo della lingua fiorentina, che migliora dopo un viaggio di Manzoni compiuto a Firenze di qualche mese, il così detto "lavare i panni in Arno".(Pag. 760)
Dal punto di vista narrativo, i Promessi Sposi, sono un romanzo storico con un narratore esterno, non sono i personaggi a raccontare le vicende, onnisciente, cioè sa già tutto della storia, questo gli consente di poter fare dei salti di scena. È anche un narratore esplicito, cioè esprime la sua opinione, commenta, giudica e valuta le vicende. Inoltre dialoga con il lettore, questo è una prova di come il romanzo risponda ai principi della poetica, cioè utile, porta insegnamenti e fa riflettere, vero o verosimile ed interessante.

ADELCHI (Alessandro Manzoni)

Nell' VIII secolo i franchi, guidati da Carlo Magno intervengono contro i longobardi in aiuto del papa.
Carlo Magno è sposato con Ermengarda, la figlia di Desiderio, re dei longobardi. Carlo Magno ripudiò sua moglie apposta per poter dichiarare guerra al regno longobardo.
Adelchi è il figlio di Desiderio, che diventerà il comandante dell'esercito longobardo, il quale però sentirà che questa guerra è ingiusta, perchè il popolo italiano viene appunto oppresso dai longobardi.
Ricordiamo una famosa frase di Adelchi "in questo mondo si è destinati a far torto o patirlo", con la quale divide in due l'umanità, gli oppressi e gli oppressori. Con questo afferma che solo dopo la morte gli oppressi troveranno la pace.(Pag. 743-744)

ALESSANDRO MANZONI

Alessandro Manzoni nasce nel 1785 a Milano da Giulia Beccaria e Pietro Manzoni. La sua principale vita da scrittore fu nella prima metà dell'800, con una formazione letteraria influenzata parecchio dalla cultura illuminista. Nel 1810 avviene la conversione, che consiste nel ritorno di Manzoni alla fede Cattolica, facendone un momento essenziale della sua vita, che farà notare il radicale cambiamento rispetto agli scritti precedenti alla conversione.(Pag. da 721 a 724)
Da qui infatti vedremo come in tutti gli scritti sarà presente il riferimento alla Bibbia e alla religione. Inoltre Manzoni cercherà di cambiare il linguaggio delle sue opere, tentando di renderlo più comprensibile a molti e più popolare.
Manzoni basa i suoi scritti su dei principi che considera ideali e che sono sempre presenti, essi sono:
-UTILE: ogni poesia deve essere utile e deve avere uno scopo, un obbiettivo personale o di sensibilizzazione e istruzione del lettore.
-VERO: le poesie devono avere delle fondamenta e delle basi di realtà e verità.
-INTERESSANTE: la lettura deve interessare il lettore, lo deve sensibilizzare e renderlo partecipe.
(Pag. 729,739,740)



mercoledì 1 maggio 2013

IL ROMANZO NEL ROMANTICISMO

Il romanzo, genere letterario nato nel 600 con sviluppo nel 700, trova nel XIX secolo il suo massimo sviluppo. Per romanzo intendiamo un componimento letterario narrativo scritto in prosa, che si rivolge ad un pubblico medio. Nell'800 il romanzo presenta diversi sottogeneri:
-Romanzo Storico:
Con questo termine indichiamo un'opera che racconta vicende inventate, ambientate però in un contesto e in un epoca storica più o meno fedelmente ricostruita. Uno dei più grandi romanzi storici fu il "Ivanhoe" di Walter Scott, che ispirò il romanzo di Alessandro Manzoni "I Promessi Sposi".
-Romanzo Fantastico:
Con questo termine intendiamo un'opera che narra storie e vicende fantastiche, popolate da elementi irrazionali come mostri, streghe e fantasmi. Troviamo un analisi del subconscio dell'uomo e degli elementi oscuri e irrazionali che compongono il suo animo. Un esponente di questi romanzi fu Hoffman con il suo romanzo "L'elisir del diavolo".
-Romanzo Realistico-Sociale:
Questo tratta storie dell'epoca contemporanea, nel quale lo scrittore tende a rappresentare la vita e la società contemporanea. Un esempio possono essere Dickens e Henri Beyle, conosciuto come Stendhal, con il suo famoso romanzo "Il rosso e il nero", nel quale troviamo anche il tema dell'amore, visto come una passione incontrollabile che va contro ogni cosa; il romanzo è ambientato nella Francia della restaurazione.

In Italia il sottogenere assolutamente dominante è quello del romanzo storico, che molto spesso tratta di sentimenti patriottici e di politica. Massimo D'Azeglio scrive di un episodio che tratta di una sfida tra soldati mercenari italiani e francesi, con a capo di quelli italiani Ettore Fieramosca e con uno sfondo storico che vede la guerra tra Francia e Spagna per l'egemonia sulla penisola italiana.

ROMANTICISMO IN ITALIA (Pag.611,616,617,623)

In Italia il movimento romantico si diffonde tardi rispetto agli altri paesi, questo è dovuto principalmente al forte legame con la cultura classicista. Iniziò a diffondersi principalmente tra il 1814 e il 1815. Nel 1814 compare la traduzione del trattato tedesco "De l'Allemagne"(La Germania) sulla rivista "La biblioteca italiana", da parte della scrittrice Madame de Staèl. Nel 1816, sempre a opera di se Staèl, compare un articolo sulla maniera e l'utilità delle traduzioni, in cui invita i letterati italiani a tradurre i propri scritti e cambiare lo stile di scrittura in quello romantico. Da qui si crea una discussione accesa tra classicisti e romantici, quest'ultimi pubblicano una serie di articoli di cui il più famoso fu "La lettera semi-seria" di Giovanni Berchet, anche questa pubblicata sulla "biblioteca italiana".
Berchet distingue 3 categorie di persone:
-parigini: intellettuale raffinato
-ottentoti: gli analfabeti
-popolo: persone che sanno leggere e scrivere, facenti parte del ceto medio e sono le persone a cui devono essere indirizzate le opere secondo lui.
Molto spesso i romantici in Italia, sono politicamente liberali, non è un caso che la rivista "il conciliatore" di Milano di idee liberali, venga bandita dopo un solo anno di vita da parte dell'impero austriaco.
Ricordiamo anche l'importante collegamento tra romanticismo e rinascimento, che influenza la produzione letteraria in Italia, riprendendo anche tematiche politiche all'interno dei testi scritti e delle opere.
Nella seconda metà del secolo, sboccia la vena sentimentale, questo periodo venne chiamato secondo romanticismo. Torna però, il problema della lingua, riemergendo come uno dei temi fondamentali, dato che gli scrittori non sapevano in quale lingua scrivere le loro opere. Anche qui emergono molte proposte come l'adozione della lingua fiorentina, oppure, da parte dei "puristi", l'utilizzo del linguaggio di Petrarca e Boccaccio. Alla fine viene utilizzato maggiormente lo stile e il linguaggio di Alessandro Manzoni, anche se alcuni come Leopardi, decidono di adottare una lingua diversa.
Nel romanticismo gioca un ruolo fondamentale l'opera lirica, anche a livello di un pubblico popolare. Il massimo esponente dell'opera lirica fu Giuseppe Verdi, le cui opere hanno una forte componente storico-politica.

giovedì 18 aprile 2013

STUDIO DI FUNZIONI

Schema per lo studio di funzioni a una variabile (x) by Davide Marrazzo:

domenica 14 aprile 2013

ROMANTICISMO

L'aggettivo "romantico" compare per la prima volta in Inghilterra, verso la metà del 600, con significato spregiativo per indicare quanta fantasia e falsità era presente nei romanzi cavallereschi. Viene ripreso poi in Germania a fine 700, dagli scrittori della rivista Athenaeum, per definire la cultura moderna in netta contrapposizione con quella classica. Secondo costoro la sensibilità classica è caratterizzata da equilibrio e armonia, mentre quella moderna da squilibrio e una mancanza di qualcosa, caratteristiche della vita dell'uomo romantico.
Oggi con il termine romanticismo indichiamo il movimento culturale che caratterizza la prima metà dell'800, appunto durante l'espansione della rivoluzione industriale, l'affermazione del ceto borghese, l'età della Restaurazione e dei movimenti nazionalisti. Nell'uso comune questo termine viene usato per indicare una generica inclinazione al sentimentalismo e alla fantasticheria.
Uno dei tratti caratteristici della cultura romantica è l'elaborazione dell'idea di nazione, l'altro è la riscoperta del Medioevo. Quest'ultimo è visto come nascita e principio delle nazioni moderne. In campo artistico e letterario c'è una netta contrapposizione tra Romanticismo e Classicismo.

ROMANTICISMO           vs           CLASSICISMO
-storicità dell'arte                              -seguire delle regole e dei modelli
-soggettività del gusto                      -tutto segue degli standard considerati perfetti
-rifiuto delle regole
-originalità

Nel Romanticismo è fondamentale la valorizzazione dell'individuo:

INDIVIDUO
-eroe romantico
-conflitto con la società
-stato di malessere, insoddisfazione:
                               -ribellione
                               -vittimismo

giovedì 11 aprile 2013

TABELLE DELLE PAGINE A PIÙ LIVELLI

Le tabelle delle pagine a più livelli consistono nell'utilizzare tabelle delle pagine di livello superiore, che contengono un riferimento ad altre tabelle di livello inferiore e così via. In poche parole, se abbiamo che nella tabella di 1° livello (non è un sayan) ci sono 10 elementi, ognuno di questi servirà come riferimento per puntare ad una tabella specifica di secondo livello, dove quest'ultima potrà contenere anch'essa riferimenti ad altre tabelle, oppure potra essere di "ultimo livello", cioè contenere riferimenti a pagine fisiche e terminare così la catena di tabelle.
Il vantaggio di utilizzare questo metodo per gestire le pagine, sta nel fatto che quando un processo viene mandato in esecuzione, si caricano in memoria solo le tabelle necessarie alle pagine di quel processo, lasciando quelle che non servono fuori dalla memoria. In questo modo, come si può notare, si ha un aumento di velocità nel raggiungere la pagina fisica ed anche un risparmio di spazio occupato, in memoria, dalle tabelle.



MEMORIA SEGMENTATA


Fino ad ora abbiamo visto una memoria virtuale con un singolo spazio di indirizzamento che parte dall’indirizzo 0 fino ad arrivare all’indirizzo massimo N.
Con la memoria segmentata, invece, viene divisa la memoria in segmenti.
Ogni segmento parte dell’indirizzo 0 a può arrivare fino ad una grandezza massima n anche se non è detto che ci arrivi: il segmento ha il grande vantaggio di essere espandibile e contraibile a seconda delle necessità.
Lo stack, ad esempio, può espandersi se si scrive una variabile al suo interno e si contrae se si preleva una variabile.
Ogni segmento è completamente indipendente dagli altri: in questo modo si può espandere e contrarre come vuole senza andare ad intaccare o “disturbare” altri segmenti di memoria (cosa che succede con una memoria non segmentata portando anche gravi problemi e sprechi di tempo dovuti alla continua rilocazione delle pagine).
Per accedere ad un’istruzione l’indirizzo di una memoria segmentata deve essere diviso in numero di segmento e offset.
Siccome i segmenti sono distini e separati tra di loro, essi sono molto comodi: immaginiamo di dover trovare un alunno in una scuola con 10.000 iscritti (in questo caso l’alunno è una procedura, una funzione così via...): la ricerca sarebbe molto più veloce se conoscessimo (prima del nome e del cognome dell’alunno) anche la classe dello studente.
Basterebbe collegare l’informazione della classe e dell’alunno e andare a pescare la persona giusta, cosa che sarebbe molto più laboriosa se non conoscessimo la classe perchè dovremmo andare a cercare il nome tra 10.000 studenti.
Un’altro vantaggio, molto importante su grossi sistemi o durante la progettazione di grossi programmi, è la possibilità di compilare singole procedure e non tutto il programma. Se in un nostro programma modifichiamo un procedura, non andrà ricompilato tutto il codice, perchè sono stati modificati gli indirizzi di memoria solo della procedura che appartiene ad un segmento, mentre tutti gli altri segmenti sono rimasti invariati.
Un altro vantaggio della memoria segmentata è sicuramente la facilitazione della protezione: siccome ogni segmento contiene una serie di oggetti dello stesso tipo (un segmento contiene, ad esempio, solo dati o stack, ma non entrambi), posso specificare anche che tipo di protezione tenere per quel segmento specifico specificando permessi di lettura/scrittura/esecuzione.
In un sistema segmentato, la protezione ha senso per il semplice motivo che il programmatore è conscio dell’esistenza dei segmenti e sa con precisone cosa ci sia all’intero di ogniuno, cosa che non succede con un sistema a singolo spazio di indirizzamento paginato.
Le librerie grafiche di un computer, che solitamente sono molto estese e pesanti, verranno messe in un segmeno con protezione bassa in modo da poterle condividere con altri programmi (in questo modo gli altri programmi eviteranno di compilare le proprie librerie grafiche perchè utilizzano quelle del computer).
La sostanziale differenza tra paginazione e segmentazione è che i segmenti non hanno una dimensione fissa.
Quando i segmenti vengono caricati o scaricati dal disco molte volte, si può creare una frammentazione esterna e per questo, ogni tanto, il sistema operativo procederà alla compattazione.

WORKING SET


Una cosa molto interessante da notare è che ogni proceso fa riferimento ad una piccola quantità di pagina e non a moltissime pagina tutte insieme.
Un compilatore a più passate, per esempio, fa riferimento a poche pagine di memoria per ogni passata.
L’insieme della pagine che vengono utilizzate correntemente da un processo si chiama working set (o zona di lavoro).
Il working set dovrebbe essere caricato tutto in memoria in modo da evitare dei fault di pagina continui che porterebbero al rallentaento della pagina (thrashing).
Cosa succede su un processo viene scaricato in memoria e poi deve riprendere l’esecuzione?
In teoria basterebbe semplicemente non far nulla. Il processo genererà moltissimi fault di pagina fino a che il suo working set non sia stato caricato in memoria per poi riprendere l’esecuzione.
Il problema sta nel fatto che il computer potrebbe metterci alcuni millisecondi per gestire un fault di pagina. E se abbiamo migliaia di fault?
La soluzione è implementata in molti sistemi operativi moderni: viene tenuta traccia dei working set di ogni processo e non si permette al processo di ricominciare a lavorare prima che il suo working set non sia stato caricato in memoria in modo da evitare fault di pagina (questa procedura si chiama prepaging).
Il working set è sostanzialmente l’insieme di pagine usate nei k riferimenti di memoria più recenti.

ALGORITMI DI RIMPIAZZAMENTO DELLE PAGINE


Quando si genera un fault di pagina, il Sistema Operativo deve scegliere quale pagina scaricare dalla memoria.
È evidente che la scelta non può essere casuale perchè si rischierebbero rallentamente pesanti nella macchina.
I progettisti di computer hanno individuato un algortimo ottimale (che non può essere realizzato) per poi tentare di riprodurlo.
L’algoritmo ottimale dice che ogni pagina deve essere contrassegnata con il numero di istruzioni macchina che vengono eseguite prima che a quella pagina si faccia riferimento.
La pagina con il numero più alto viene scaricata.
Ovviamente questo algoritmo ha un implementazione impossibile perchè è impossibile determiare il numero di istruzioni che occorrono prima del riferimento alla pagina.

I progettisti hanno allora cercato degli algortimi che potessero aiutare veramente durante la progettazione di un computer:

Il primo algoritmo chiamato NRU ha bisogno, per essere utilizzato, di due bit: un bit R che viene messo a 1 quando si fa un riferimento alla pagina (lettura o scrittura) e un bit M che viene messo a 1 quando si fa una scrittura alla pagina.
Periodicamente, il bit R viene rimesso a 0 dal sistema operativo mentre l’M viene mantenuto ad 1 se la pagina è stata modificata.
Il sistema operativo, in questo modo, è in grado di classificare ogni pagina in 4 categorie:
Classe 0: non usata e non modificata (0,0)
Classe 1:non usata, modificata (0,1)
Classe 2: usata, non modificata (1,0)
Classe 3:usata,modificata(1,1)
Quando si genera un fault di pagina, il sistema operativo scarica dalla RAM una pagina casuale presa dalla classe più bassa non vuota.

Un altro algoritmo di rimpiazzamento è detto algoritmo FIFO.
É un algoritmo di facile implementazione, infatti, quando si genera un fault di pagina, viene scaricata dalla RAM la pagina che è presente da più tempo in memoria.
Il problema di questo algoritmo è evidente: anche se una pagina è vecchia, cioè da molto tempo in memoria, non vuol dire che sia inutile.

Una combinazione tra NRU e FIFO è l’algoritmo della seconda opportunità: quando si va in contro ad un fault di pagina, si va a cercare l’elemento più vecchio, cioè quello in coda alla lista.
Una volta che abbiamo trovato l’elemento più vecchio, si controlla il suo bit R. Se è a 0, vuol dire che la pagina è vecchia e non usata e allora la pagina viene scaricata su disco.
Se il bit R è a 1, viene messo a 0 e la pagina viene spostata in testa alla lista come se fosse stata appena caricata.
A questo punto si cotinua a cercare una pagina in fondo alla lista con bit R a 0.

L’algorimo dell’orologio consiste in questo: si mantiene una lista circolare di pagina con la lancetta che punta su una pagina. Se ad un fault di pagina la lancetta punta su una pagina con bit R a 0, la pagina viene scaricata, viene portata la lancetta avanti di uno e la pagina che deve entrare in memoria viene sostituita alla pagina appena scaricata.
Se il bit R e a 1, viene messo a 0 e la lancetta spostata in avanti fino a quando non si trova una pagina con bit 0.

Una buona approssimazione dell’algoritmo ottimale e quella offertaci dall’algoritmo LRU.
Questo algoritmo consiste nello scaricare dalla memoria la pagina non usata da più lungo tempo.
Un modo per implementare la LRU e quello di avere un contatore a 64 bit e che ogni pagina contenga abbastanza spazio per memorizzare il contenuto del contatore.
Dopo ogni riferimento in memoria, il valore del contatore viene memorizzato nella pagina a cui si è fatto riferimento.
Quando si va in contro ad un fault di pagina, viene scaricata dalla memoria la pagina con il valore del contatore più basso (la pagina corrispondente al contatore più basso e la pagina usata meno di recente).
Un altro metodo per implementare la LRU e quello di mantenere una tabella n*n (n numero delle pagine fisiche). Quando si fa un riferimento ad un pagina k , viene messa a 1 tutta la riga k e a 0 la colonna k.
Quando si genera un fault di pagina si controlla il valore binario di ogni riga: la riga con il valore binario più basso è quella usata meno di recente.
Queste implementazioni della LRU vengono eseguite via hardware. Il problema è che nessuna macchina possiede tale hardware.

Per questo si è cercato di simulare la LRU via software e si è riusciti con l’NFU.
Ad ogni pagina è associato un contatore e ad ogni interruzione di clock viene sommato il contatore al bit R della pagina.
Quando si verifica un fault di pagina, viene scelta la pagina con il contatore più basso.
Dopo varie simulazioni si è notato che anche questo algoritmo non è il massimo dell’efficienza, perchè non dimentica mai nulla e potrebbe essere che vengano scaricate su disco delle pagine che servano nell’immediato futuro.
Una modifica dell’NFU, chiamata algoritmo dell’invecchiamento, permette una resa ottimale e una buona approssimazione all’algoritmo ideale.
Come implementare tutto ciò?
Ogi pagina ha una serie di bit (8) che all’inizio vengono messi tutti a 0. Dopo ogni ciclo di clock, gli 8 bit vengono shiftati a destra di una posizione e viene messa nella posizione ora vuota il bit R.
Quando si genera un fault di pagina viene scaricata la pagina con la serie di bit più bassa.

TLB (Memoria Associativa)


Osservando l’utilizzo della memoria di un calcolatore, potremmo notare che la maggior parte dei programmi accede a poche pagine di memoria molto di frequente e non a molte pagine poco frequentemente.
Per sfruttare questa condizione vantaggiosa, i progettisti hanno creato una sorta di MMU ridotta ad accesso parallelo chiamata TLB.
All’interno della TLB vengono salvati alcuni dati relativi ad ogni pagina virtuale usata spesso.
Quando arriva alla MMU un indirizzo virtuale, prima di fare un controllo sulla tabella della pagine, viene controllato ogni elemento della TLB simultaneamente e se nella TLB è presente questo elemento, viene data subito la pagina fisica, senza bisogno di accedere alla lenta tabella delle pagine.
Se invece la pagina virtuale non è presente nella TLB, si genera una page miss, viene cercata nella tabella delle pagine la pagina virtuale, viene scaricata una pagina dalla TLB e rimpiazzata con la pagina appena trovata sulla tabella delle pagine.

MEMORIA VIRTUALE E MMU


Il ragionamento dietro alla memoria virtuale consiste nel fatto che un programma può essere più grande della memoria fisica.
Il programma viene diviso in modulo (overlay) e solo quelli necessari all’esecuzione vengono caricati in RAM mentre le restanti parti restano sul disco.
Un programma da 4 GB può girare tranquillamente su una memoria da 2GB scegliendo accuratamente quali 2GB mandare in esecuzione.
La memoria virtuale ora introduce anche il concetto di paginazione: la memoria viene divisa in partizioni dette pagine e ogni pagina è grande solitamentre 4 KByte.
In un sistema a 32 bit, ci sono 12 bit che servono per “muoversi” all’interno della pagina (2^12 = 4KB) e il restante 20 bit servono ad indicare la pagina a cui facciamo riferimento.
Da questo deduciamo che appunto con 12 bit di offset le pagine posso essere grandi massimo 4KB e che ci possono essere al massimo 2^20 pagine (1 milione di pagine).
(1 milione di pagine per 4KB l’una sono 4 giga).
Ora però l’indirizzo della pagina virtuale non corrisponde a quello della pagina reale.
Come risolvo questo problema? Sulla scheda madre c’è un componente chiamato MMU che fa da traduttore: prende l’indirizzo della pagina virtuale e lo trasfororma in indirizzo reale.
La MMU contiene appunto una tabella delle pagine che è compilata dal gestore della memoria. Il gestore della memoria, infatti, tiene conto delle pagine libere e è in grado di dire dove una pagina virtuale deve puntare sulla memoria reale.
Su un sistema a 32 bit, 12 bit vanno direttamente in memoria e 20 bit, invece, si fermano sulla MMU. Questi 20 bit compongono l’indirizzo virtuale della pagina richiesta, ma prima che la scheda di memoria onori la richiesta, questo indirizzo virtuale deve essere trasformato in indirizzo reale tramite la MMU.
Ovviamente in memoria virtuale abbiamo, ad esempio, 100 pagine virtuali, mentre in memoria reale sono 10 pagine.
Capiamo quindi che sono 10 pagine virtuali avranno un corrispettivo in memoria reale. Ogni pagina virtuale ha quindi un bit che che messo a 0 vuol dire che la pagina non è mappata, se è a 1 vuol dire che è mappata.
Cosa succede ora se per caso si deve accedere ad una pagina virtuale che non ha un corrispettivo nella memoria fisica?
In una situazione di questo genere si crea un fault di pagina: viene prelevata una pagina (algortimi di rimpiazzamento della pagine dopo) dalla memoria fisica, se è stata modificata viene riscritta su disco, altrimenti no.
Sulla sua pagina virtuale, viene messo un bit a 0 che sta a significare che quella pagina virtuale non ha più un corrispettivo nella memoria reale.
Ora viene presa la pagina virtuale a cui si deve accedere e viene scritta sopra la precedente pagina; si modifica la MMU per far puntare quella pagina virtuale a quella pagina fisica e viene messo un bit a 1 per dire che quella pagina virtuale ha un corrispettivo nella memoria reale.
Con un sistema a 32 bit, ci sono 2^20 pagine virtuali che corrispondono a oltre un milione di pagine virtuali.
L’indirizzo della pagina virtuale viene usato come indice della tabella delle pagine e il contenuto della corrispondente cella è l’indirizzo di memoria fisica.
In un sistema a 64 bit, il numero di pagine virtuali è 2^52 che sono moltissime.
Con così tante pagine virtuali, la velocità e la stabilità dal sistema sono seriamente compromesse e per questo si utilizzano metodi diversi per l’accesso alle istruzioni.
Un metodo è la tabella delle pagine inverse.
Nella tabella delle pagine normale, ci sono tante celle quante sono le pagine virtuali.
Nella tabella della pagine invertite, ci sono tante celle quante sono le pagine fisiche: la CPU emette un indirizzo a 32 bit, 12 di offset e 20 di pagina virtuale.
Al posto di andare all’indice dettato da 20 bit, si cerca nel contenuto delle celle il corrispettivo numero dei 20 bit e quando lo si trova si prende l’indice e quella è la pagina fisica.
Se non si trova l’elemento abbiamo un fault di pagina.
In sostanza le pagine fisiche fanno da indici per la tabella e quelle reali da contenuto.


POLITICHE DI GESTIONE DELLA MEMORIA


Quando la memoria viene gestita e allocata dinamicamente, è sempre bene tenere conto della memoria utilizzata e di quella non utilizzata.
Il primo modo di tracciare l’utilizzo della memoria è quello con le bitmap.
Viene creata una grande matrice formata da 0 e 1. La memoria viene divisa in piccole partizione e a ogni partizione viene associata una casella della bitmap. Se c’è 1 nella bitmap, la partizione è occupata, altrimenti è libera.
Il secondo metodo per tenere traccia dell’utilizzo della memoria è il metodo a liste: il sistema operativo tiene una lista concatenata di spazi liberi e occupati in memoria con le informazioni riguardanti la dimensione.
In ogni nodo della lista sono presenti tre informazioni: se la regione di memoria è libera, l’indirizzo di inizio e di fine di quella regione.
Quando spazi e buchi vengono ordinati nella lista in ordine di indirizzo, possiamo poi usare diversi algoritmi per allocarle la memoria ad un processo.
Il primo metodo è detto di first feet, cioè il gestore della memoria trova il primo buco sufficientemente grande per contenere il processo, divide il buco in 2 parti: uno spazio per il processo e uno spazio che diventa un altro buco più piccolo. Altri algoritmi sono il next feet, il best feet, worst feet e il quick feet.

SWAPPING


Lo swapping consiste nel caricare e scaricare in RAM un processo a seconda delle esigenze. Se un processo deve essere eseguito sul processore, Il processo viene mosso dal disco alla memoria, eseguito e poi riportato su disco per permettere ad altri processi di occupare quell’area di memoria.
Assistiamo quindi ad una gestione dinamica della memoria: le partizioni non hanno mai stesse dimensioni e la stessa posizione.
La gestione dinamica della memoria utilizzata nello swapping consente una maggiore flessibilità, ma implica anche una maggiore difficoltà a causa della continua rilocazione delle partizioni.
Una cosa molto importante è anche la quantità di memoria che va allocata per ogni processo: se ogni processo avesse una dimensione fissa, basterebbe allocare la quantità di memoria che serve, ne più ne meno.
Il problema sta nel fatto che spesso i processi si modificano in dimensioni e quindi è sempre meglio allocare una dimensione di memoria superiore per evitare problemi di segmentation fault.

RILOCAZIONE E PROTEZIONE


La multiprogrammazione porta con se anche due grandi problemi: la rilocazione e la protezione.
Quando compiliamo un programma viene generato un file binario contenente delle istruzioni. Supponiamo che la prima istruzione sia una chiamata ad una funzione in posizione 100 e che la partizione di memoria del processo inizi in posizione 350. Il processo dovrebbe eseguire l’istruzione in posizione 350 + 100 e non in posizione 100. Quindi il problema consiste nel trasformare l’indirizzo di memoria assoluto, in quello relativo alla proprio partizione di memoria. Il problema viene comunemente risolto semplicemente aggiungengo 350 durante la chiamata a quella istruzione. Questo però non risolve il problema della protezione, infatti si potrebbero creare delle istruzioni che utilizzino direttamente indirizzi assoluti e non relativi.
IBM risolse questo problema con 4 bit che definivano cosa si potesse fare in una determinata sezione di memoria. Il file che conteneva questi 4 bit si chiamava PSW.
Un’altro modo per risolvere entrambi i problemi era i registri di base e limite. In quello di base, era contenuto l’indirizzo dove iniziava la partizione e in quello di limite dove finiva la partizione: se durante la trasformazione da indirizzo assoluto a indirizzo relativo veniva sforato il limite sia positivamente che negativamente, il processo veniva killato.
Inoltre, ad ogni chiamata ad un indirizzo, veniva sommato all’indirizzo il registro base per trasformare da indirizzo assoluto a indirizzo relativo.

ORGANIZZAZIONE DELLA MEMORIA


L’organizzazione della memoria più avvenire così in due modi: con diverse code o in singola coda.
Nel primo caso tutti i processi “piccoli” si accodano dove c’è la partizione più piccola che possa contenere il singolo processo e lo stesso vale per i processi “grandi”. Il problema di questo modo di usare la memoria è che potrebbe accadere che la coda dei processi piccoli sia piena, mentre la coda dei processi grandi sia vuota: in questo caso i processi piccoli in fondo alla coda aspettano di essere caricati in memoria, mentre in realtà la memoria è quasi totalmente vuota perchè le partizioni grandi che dovrebbero contenere processi grandi sono vuote.
La coda singola è diversa, cioè viene creata una singola coda contenete processi grandi e piccoli.
Quando viene liberata una partizone di memoria, viene cercato nella coda il processo che sprechi meno memoria mettendosi in quella partizione.
Il problema di questo tipo di gestione della memoria è che i processi piccoli vengono discriminati mentre in realtà dovrebbero essere privilegiati.

GESTIONE DELLA MEMORIA (Introduzione)


Come sappiamo, all’interno di un computer esistono diversi tipi di memorie diverse per velocità, capacità e prezzo.
In un computer ideale, tutte le memorie sarebbero enormi, molto economiche e velocissime, ma dato che ciò non è possibile, i progettisti hanno deciso di creare diversi tipi di memoria: la Cache, molto veloce, molto piccola e molto costosa, la RAM, abbastanza capiente, abbastanza veloce e mediamente costosa e la memoria di massa, lenta, molto capiente e economica.
Il gestore della memoria ha il compito di gestire e organizzare le memorie nel modo più efficiente possibile, tenendo conto delle pagine di memoria usate e quelle non usate, compilando la tabella delle pagine nella MMU e svolgendo molti altri compiti che vedremo più avanti.

Nel caso di un sistema monoprogrammato (cioè che può eseguire un processo alla volta), la gestione della memoria è molto semplice, infatti, è possibile caricare in RAM un processo alla volta e fino a quando non viene portato a termine, esso non verrà scaricato dalla RAM.
In un sistema monoprogrammato ci sono tre diversi modi di gestire la memoria: il SO nella parte bassa della RAM, il SO in ROM, oppure il SO nella parte bassa della RAM e il gestore delle periferiche in ROM.

Ai giorni nostri, però, la monoporgrammazione non è più contemplata e si è passati alla multiprogrammazione, dove più processi risiedono in RAM in attesa di essere caricati ed eseguiti sulla CPU.
Il modo più semplice per realizzare la multiprogrammazione è dividere la memoria in blocchi fissi, magari di dimensioni diverse.
Quando un processo viene caricato in RAM, viene cercata la partizione più piccola disponibile che possa contenere il processo.

mercoledì 10 aprile 2013

DEI SEPOLCRI (Ugo Foscolo)

Questo componimento fu scritto da Foscolo nel 1806, a seguito di una discussione con il letterario Pindemonte a cui è dedicata l'opera. È composto da 295 versi endecasillabi sciolti. Fu scritto in occasione dell'editto di Saint-Cloud, dove venne approvata una legge che imponeva di spostare i cimiteri(sepolcri) fuori dalle città e di rendere tutte le tombe uguali tra di loro. Foscolo sviluppa un ragionamento intorno al tema delle tombe, riflettendo sul perchè l'uomo ne abbia bisogno e sul loro valore simbolico.

Spezzoni letti in classe:
-IL VALORE AFFETTIVO DEI SEPOLCRI (pag.567)
Nella prima parte Foscolo esprime i suoi sentimenti puramente materialistici, in cui vuole risaltare come le tombe siano sostanzialmente inutili. Nella seconda parte, invece, sottolinea il valore delle tombe e di come servano all'uomo per mantenere vivo il ricordo dei suoi cari.
-LA FUNZIONE DELLE TOMBE DEGLI UOMINI ILLUSTRI (pag.575)
La vera capacità eternatrice del ricordo dei morti è data dalla poesia, che serve per continuare a mantenere vivo il ricordo nel tempo, le gesta e gli ideali degli uomini illustri, così che le generazioni future possano prendere spunto da essi.

I SONETTI (Ugo Foscolo)

Nei sonetti di Foscolo troviamo un maggior distacco più profondo dei propri sentimenti rispetto alle lettere di Jacopo Ortis, furono composti tra il 1798 e il 1803. Il linguaggio è sempre di tono elevato e letterario. I sonetti sono nati nel 1200 nella scuola siciliana; in quelli di Ugo Foscolo, troviamo molti enjambemant e 4 strofe formate da rime e versi endecasillabi.
I principali sono essenzialmente 4:
(Wikipediata)

-Alla Sera:
Nell'immobile silenzio della sera, quando ogni forma di vita si spegne, il silenzio suggerisce al poeta l'immagine della morte alla quale egli si rivolge con nostalgia, come se essa potesse portare solamente la pace. La morte non è più vista come una drammatica sfida al destino, come nell'Ortis, ma come un dolce perdersi nel nulla eterno che non è un disperato abbandono, ma è un comprendere in sé l'universo superando ogni angoscia e ritrovando la pace.

-A Zacinto:

A Zacinto ("Né più mai toccherò le sacre sponde") è uno dei sonetti più conosciuti di Ugo Foscolo. Zacinto, qui cantata dal poeta, non è solamente la sua patria reale ma soprattutto quella ideale. Come altri poeti romantici il Foscolo si protende alla Grecia classica nella quale vede, attraverso i suoi miti, l'incarnazione della bellezza e dell'armonia. Venere raffigura l'ideale della bellezza, Omero rappresenta la poesia che esalta i valori più alti dell'umanità e Ulisse non è altro che l'immagine di se stesso esule avversato dalla fortuna.Il sonetto si conclude con il presentimento di una sepoltura in terra straniera che il Foscolo accetta perché confortato dalla fede in una propria missione nel mondo come evocano gli ultimi versi pieni di dolore ma senza lacrime.
-Alla Musa
-In morte del fratello Giovanni

venerdì 15 marzo 2013

L'Italia e le rivoluzioni: 1846 - 1849

1846 - 1847: le riforme

Nel 1846 diventa Papa Giovanni Mastai Ferretti, con il nome di Pio IX.
Il nuovo pontefice, con la nomea di essere un liberale, inizierà il biennio di riforme che contraddistinguerà tutta l'Italia: l'amministrazione viene leggermente modificata, ma il sogno delle Costituzioni rimarrà tale.

Il caso palermitano

12 gennaio 1848: Palermo insorge e chiede, oltre all'indipendenza siciliana da Napoli, una Costituzione.
Federico II, il re italiano più anti-riformista dell'epoca, la concede.
Questa svolta obbliga anche altri re a dare ai cittadini uno statuto:
  •  Leopoldo II in Toscana;
  • Pio IX a Roma;
  • Carlo Alberto concede, nel regno di Sardegna, lo Statuto Albertino che rimarrà in vigore fino al 1948;
Le rivoluzioni in Lombardia e Veneto

Viene il momento di ribellarsi anche nel regno Lombardo - Veneto sottomesso all'Austria.

17 marzo: insorge Venezia: gli austriaci vengono cacciati e viene proclamata la Repubblica di San Marco.

18 marzo: il popolo (studenti, professionisti e operai) di Milano si ribella. Iniziano così le "cinque giornate di Milano" che vedono la vittoria dei civili contro le armate imperiali.
Il clima politico che si crea nella città meneghina vede combattere due forze:
  • Moderati - Gabrio Casati, capo provvisorio della città, è favorevole a un intervento piemontese;
  • Democratici - Carlo Cattaneo ("Semper lù") rivendica l'autonomia cittadina.
La questione viene risolta direttamente da Carlo Alberto che, dopo un attimo di titubanza, interviene e dichiara "Guerra bastardi!" all'Austria il 23 marzo.

La prima guerra d'indipendenza

Carlo Alberto, spinto da mire espansionistiche e dalla difficoltà austriache - l'Impero è un focolaio di tumulti sociali in questo momento - dichiara guerra il 23 marzo 1848.
Volontari e truppe inviate da ogni regno d'Italia accorrono per dar manforte all'esercito piemontese,  questo fatto è indicato come "Prima guerra d'indipendenza".
Le continue sconfitte convincono Pio IX a ritirare i suoi uomini dal conflitto, seguito a ruota dagli altri re italiani.
A Custoza, vicino a Verona, si svolge la battaglia decisiva tra il 23 e il 27 luglio: vince l'Austria e il Piemonte chiede l'armistizio.

La fase democratica

A Roma e Firenze sommosse popolari portano alla creazione di una Repubblica democratica con a capo un triumvirato, verso la fine del 1848.

Repubblica Romana - il triumvirato di Mazzini, Saffi e Armellini ha idee molto moderne:
  • nazionalizzazione dei beni della Chiesa, rimane però solo un'idea;
  • Costituzione completamente differente dagli altri Statuti.
Il comando militare viene dato a Garibaldi, di ritorno dal Nuovo Mondo.

La sconfitta delle rivoluzioni

Carlo Alberto tenta di lanciare nuovamente guerra all'Austria, ma viene subito sconfitto a Novara (27 marzo 1849). Abdica a favore di Vittorio Emanuele II.

A Roma, Pio IX torna in possesso della città con l'aiuto dei francesi nel luglio 1849.

Venezia venne sconfitta per ultima ad agosto, stremata dalla fame e da un'epidemia di colera, e torna sotto il dominio austriaco.











giovedì 14 marzo 2013

Il 1848 in Italia - Premesse

Situazione economica e sociale

Verso la metà dell'Ottocento, l'Italia è ancora molto arretrata e la rivoluzione industriale è solo un bella cosa che sta imperversando in Europa.
L'economia dello stivale è basata ancora su un sistema prevalentemente agricolo, con qualche isolato caso di industria tessile nel Nord Italia - la realtà italiana è divisa in due:
  • NORD: economia capitalistica, sempre agricola;
  • SUD: latifondo e mezzadria 
Inoltre, la frammentazione politica dell'Italia penalizza il suo mercato interno con molte dogane, forti dazi, monete e unità di misura diversi da qui a lì - le diverse realtà economiche non si integrano.

Questa arretratezza economica ha indubbi risvolti sociali: la borghesia è ancora schiacciata da una aristocrazia proprietaria dei campi coltivati e la classe operaia è inesistente . 

Situazione politica - Risorgimento

La debolezza economica influenzerà il Risorgimento
"Il risorgimento politico di una nazione non va mai disgiunto dal sue risorgimento economico: le condizioni dei due progressi sono identiche" (Cavour
I moti a cavallo del 1830 e del 1840 formano nella classe intellettuale le prime idee di indipendenza, correlate all'unità italiana.
Questi intellettuali iniziano così a stendere dei veri e propri progetti politici, si evidenziano due blocchi:
  • Democratici rivoluzionari
    - Mazzini: fondatore della Giovine Italia (1831), pensa a una Repubblica democratica ottenuta attraverso l'azione del popolo, istruito a dovere.
    - Carlo Cattaneo: secondo lui, le varie regioni italiane sono così diverse da non potere coesistere se non sotto una Repubblica federale.
  • Liberali moderati
    - Vincenzo Gioberti: convinto neogualfista che vuole uno stato federale con a capo il Papa, esempio etico-politico della Nazione;
    - Balbo: confederazione italiana sotto la giuda della monarchia piemontese (filo-sabaudo).


 

LE ILLUSIONI (Ugo Foscolo)

-Cosa sono le illusioni?
Le illusioni sono quelle emozioni e sentimenti che servono per dimenticarsi del male e della sofferenza, purificando e portando in un'altra dimensione il cuore e la mente di chi le prova. Il loro termine sta ad indicare appunto che gli "illusi" credono di stare bene ed avere il cuore pieno di gioia, ma non appena l'effetto svanisce anche questi sentimenti e la bellezza se ne vanno.

-Come influiscono nella vita di Jacopo e dell'uomo?
Le illusioni influiscono nella vita dell'uomo come un qualcosa di benevolo, che serve a lui stesso per poter vivere in pace e armonia. Nel caso particolare di Jacopo, si nota come esse siano la sua fonte di gioia e di vitalità, utile per superare una realtà negativa. Jacopo le descrive come un qualcosa di divino e irreale che lo portano con la mente in un mondo pieno di bellezza. Senza queste illusioni, confessa che non riuscirebbe a vivere e si "strapperebbe il cuore come un servo infedele".

Differenze tra: LO SCONFORTO PER LA SITUAZIONE DELLA PATRIA & L'INNAMORAMENTO (Ugo Foscolo)

I due componimenti sono due delle lettere inviate da Japoco Ortis a Lorenzo Alderani, la prima (lo sconforto) parla della sua patria e di come sia stata tolta ai veneziani, con un tono molto triste e cupo, nella seconda (l'innamoramento) parla del suo amore verso Teresa e come questo gli faccia dimenticare le angosce del mondo reale.
Nello "sconforto per la situazione della patria" inizialmente, nella prima parte, parla molto a sfavore dei francesi e del trattato di Campoformio, nella seconda parte torna molto un tema del ricordo dei tempi passati.
Nell' "Innamoramento" troviamo elementi felici e pieni di gioia, le frasi sono molto scandite e molto distinte tra loro; nella prima parte Jacopo descrive l'amore come qualcosa di sublime e continua a raccontare e narrare l'incontro con Teresa, nella seconda invece troviamo una riflessione sull'amore e su come questo illuda l'uomo e gli nasconda i dolori.

Differenze di forma:

mercoledì 27 febbraio 2013

1848: le Rivoluzioni europee

"Oibò! É successo un quarantotto!"
Nel 1848 avvengo, in Europa, avvenimenti sociale che faranno da base a fatti successivi e che sanciscono la fine dell'età della Restaurazione (1815 - 1848).
Tutte le zone europee si ritroveranno a fare i conti con questi moti popolari, esclusa l'Inghilterra e l'Est Europa: troppo progredita la prima e troppo arretrato il secondo.

Le motivazioni alla base di questi tumulti sono, principalmente, TRE:
  • la forte crisi economica: due anni di carestie hanno messo in ginocchio gli strati più poveri della società che diminuisce la propria domanda di prodotti industriali - emblematico il caso dell'Irlanda dove una malattia delle patate costringe alla morte un milione di persone e all'emigrazione altrettante persone;
  • le lotte di classe tra aristocrazia, borghesia e proletariato; 
  • il desiderio d'indipendenza delle zone occupate, sopratutto quelle sotto il dominio austriaco - discorso diverso per la Germania, dove verrà cercata l'unità nazionale.
Tutte le capitali dei futuri stati indipendenti (Budapest, Praga, Zagabria, Milano e Venezia) si ritrovano centro di rivoluzioni durante il mese di marzo
In un primo momento, le rivoluzioni sembrano in grado di andare a bersaglio, ma le forti frammentazioni al loro interno le faranno finire entro l'estate del 1849; l'Impero farà leva sull'esercito che rimarrà sempre fedele al Re.
Nel mentre sale al trono il giovane Francesco Giuseppe destinato, nel suo regno secolare, a far nascere l'Impero Austro-Ungarico.

La situazione francese

In Francia, troviamo - principalmente - due blocchi in contrapposizione:
  1. Liberali - Democratici - Socialisti con appoggio della media-piccola borghesia e della classe operaia
  2. Monarchia (nella figura di Luigi Filippo d'Orleans) appoggiata dalla Chiesa, della nobiltà e della grande borghesia.
Le sempre più forti tensioni sociali hanno luogo di esplodere a febbraio, quando il Governo tenta di impedire una manifestazione per l'allargamento del diritto di voto. I manifestanti reagiscono facendo cadere la monarchia e riescono ad instaurare una Repubblica, con un Governo di coalizione.
L'esecutivo dà subito luogo ad alcuni provvedimenti:
  • suffragio universale maschile;
  • abolizione pena di morte;
  • istruzione elementare gratuita;
  • abbassamento delle ore lavorative che diventano, così, 10;
  • abolizione del lavoro a cottimo: la paga non sarà più proporzionata alla quantità di pezzi prodotti;
  • istituzione degli Ateliers Nationaux: aziende pubbliche capaci di assorbire i disoccupati.
Questo Governo resiste fino al 23 aprile quando si terranno le elezioni con la vittoria dei moderati, i quali cacceranno i due rappresentati socialisti.  
Il Governo moderato riallungherà la giornata lavorativa e abolirà gli Ateliers.

I socialisti tenteranno di conquistare una poltrona in Parlamento durante il mese di giugno, ma verranno prontamente soppressi dall'esercito.

A dicembre si tengono le elezioni presidenziali, dove stravincerà un esponente dei moderati: Luigi Napoleone Bonaparte (nipote di Napoleone).
Luigi Napoleone riformerà l'Impero nel 1851 grazie al consenso borghese - i borghesi rinunciano al potere politico in cambio della calma popolare imposta da Luigi Napoleone III.




 

martedì 26 febbraio 2013

LE ULTIME LETTERE DI JACOPO ORTIS (Ugo Foscolo)

"Le Ultime lettere di Jacopo Ortis" è un romanzo epistolare, cioè formato quasi esclusivamente da lettere tra i personaggi. Foscolo finge che, un giovane di nome Lorenzo Alderani raccolga e pubblichi le lettere che un suo amico, Jacopo Ortis, gli ha scritto negli anni. L'amico, Jacopo, si è suicidato ed è per questo che Lorenzo vuole ricordarlo pubblicando le sue lettere. Jacopo Ortis è un giovane studente veneziano, di sentimenti e ideologie democratiche, che è costretto a trasferirsi a causa del trattato di Campoformio del 1797, ed è colpa della lontananza dalla patria e dell'amore non corrisposto verso Teresa, donna della quale si innamora sperduatamente, che lo portano al suicidio, considerando la sua vita come un fallimento.
Il modello del romanzo è ispirato alle opere di Goethe, su una base preromantica, dove troviamo un'anticipazione dell'eroe romantico. Per certi versi può essere considerato un romanzo dell'attuale tradizione italiana, per altri, invece, non può essere ancora considerato un romanzo moderno, perchè ancora presenta dei versi lirici e non narrati.

domenica 24 febbraio 2013

I PENSIERI DELL'800

I tre grandi sistemi di pensiero che si formano all'inizi dell'800 sono:

-Liberalismo
-Democrazia
-Socialismo

Tutte e tre le ideologie sono in contrasto e opposizione alla Restaurazione dell'Europa.
Il liberalismo si trova in ambito politico, da non confondere con il liberismo che si trova sul fronte dell'economia. Secondo il liberalismo lo Stato deve garantire la libertà individuale e tutelare i diritti fondamentali dell'individuo; per ottenere questo scopo, secondo questa ideologia, deve esserci una divisione dei poteri (legislativo, esecutivo, giudiziario). In un sistema liberale era garantita una rappresentanza popolare, anche se il diritto di voto non è considerato un diritto fondamentale della persona.
La democrazia, invece, si basa sul diritto di voto per tutti, cioè il suffragio universale. Anche se nell'800 le donne non avevano diritto di voto.
Il socialismo si preoccupa fondamentalmente dell'uguaglianza economica e sociale. Ciò che i socialisti vogliono superare sono le grosse differenze economiche all'interno della società dell'800. Essi credevano che per ottenere una società più giusta, bisognava arrivare ad un'abolizione della proprietà privata dei mezzi di produzione, che andrebbe sostituita con una proprietà collettiva. Nei dibattiti che sono emersi, prevalse l'idea di Karl Marx e Federico Engels che pubblicarono un libretto chiamato "Manifesto del Partito Comunista". In questo periodo le parole socialista e comunista erano sostanzialmente sinonimi. Secondo Marx, l'affermazione del capitalismo industriale porterà alla divisione in 2 grandi gruppi, cioè un grande numero di proletari e un piccolo numero di industriali.

venerdì 22 febbraio 2013

Età Napoleonica: PREROMANTICISMO e NEOCLASSICISMO

L'età Napoleonica è un periodo storico che va dal 1796 al 1815.
In letteratura, questi anni sono influenzati dagli ultimi strascichi di illuminismo, dal preromanticismo e dal neoclassicismo.

L'illumismo fa da culla al concetto di "bello", dove l'opera deve essere sublime e capace di smuovere l'anima dello spettatore.
Secondo Edmund Burke, all'artista non sono quindi richieste particolari abilità strettamente tecniche, ma intuizioni geniali capaci di "suscitare la più forte emozione che l'anima sia capace di sentire [in maniera analoga al terrore]": è di questo periodo la relazione tra artista e genio.

Il preromanticismo è l'avo del romanticismo che si svilupperà, poi, nel secolo successivo.
Sentimento, esaltamento della natura e una ferma opposizione a classicismo e ragione sono alla base di questo movimento culturale sviluppatosi in Inghilterra.
Queste basi ideologiche portano alla nascite di liriche in cui l'autore si produce in riflessioni sulla morte e sulla natura solitaria dell'uomo, dove l'ambiente è cupo e malinconico (tipiche le poesie cimiteriali).
Gli autori più illustri sono Thomas Gray e Edward Young.
L'opera più illustre è "Canti di Ossian" scritti , narra la leggenda, da Ossian, un leggendario poeta galeico del III sec. d.C, e raccolti dallo scozzese Macpherson (saranno poi tradotti in italiano da Melchiorre Cesarotti e pubblicati nel 1763). Questo Testo è inoltre testimone di come i preromantici tendano a riscoprire il Medioevo barbarico.

In contemporanea, nasce in Germania il movimento "Sturm und Drang" (letteralmente: Tempesta e Assalto) che condivide il pensiero anti-illuminista inglese ed esalta il ribellismo dell'artista-genio istintivo e sentimentale.
Autori importanti del movimento sono Schiller e Goethe ("I dolori del giovano Werther").

Opposto a questi due movimenti, troviamo dominante neoclassicismo della letteratura e dell'arte in un periodo di transizione così incerto.
Come si evince dal nome, questa filosofia di pensiero si basa sui canoni classici greci e romani arricchiti, però, dalle esperienze di secoli di storia.
"Il neoclassicismo" teorizza il tedesco Winckelman "è un canone naturale capace di perfezionare la natura umana".
Sempre di Winckelman è dovuto un nuovo concetto di estetica secondo cui la Grazia "agisce nella semplicità e nella quiete della anima offuscata dalle passioni (N.B: come le statue elleniche)".

Questi movimenti sono in contrapposizione tra loro, ma proprio la loro fusione (es. Foscolo) porterà alla nascita del pensiero moderno occidentale.


UGO FOSCOLO

Ugo Foscolo naque nel 1778 e morì nel 1827. Nasce a Zante (Zacinto), un isola del mar Ionio, all'ora dominata dai veneziani; proveniva da una famiglia il cui padre era veneto e la madre greca, ed è per questo che si ritiene pienamente greco. Dal 1792 si trasferisce a Venezia, la quale diventerà la sua seconda patria e lo indirizzerà ad un pensiero politico democratico. Inizialmente Foscolo e i democratici vedevano i francesi come dei liberatori, ma successivamente, dopo il trattato di Campoformio, vennero visti come traditori che avevano consegnato i veneziani agli austriaci. Ugo Foscolo poi si trasferì in molte città d'Italia e si arruolò nell'esercito della Repubblica Cisalpina. Nel 1811 il Governo di Milano interrompe le rappresentazioni di un'opera di Foscolo, dato che era presenti dei riferimenti negativi nei confronti dell'operato di Napoleone. Nel 1815 gli austriaci gli offrono un lavoro come direttore a capo di un'importante rivista del tempo, ma costui non accettò e preferì trasferirsi all'estero. Muore a Londra nel 1827 e venne sepolto a Firenze nella Chiesa della Santa Croce.

In Ugo Foscolo è presente una formazione illuminista, che conserva una aspetto laico e materialista. Nelle sue opere sono presenti molti elementi e riferimenti alla cultura classica, ma anche degli elementi come, il pessimismo e la malinconia, che sono tipici del preromanticismo. Nella visione di Foscolo l'arte e la poesia erano 2 attività fondamentali. Queste servivano per dare bellezza, armonia e serenità all'uomo e alla sua vita, per contrastare l'amara realtà.

giovedì 21 febbraio 2013

Multiprogrammazione

Per varie applicazioni è utile avere in singolo processo svariati thread in esecuzione.  Questi condivideranno il segmento di codice e il segmento dati ma avranno un segmento di stack personale.
I threads verranno schedulati automaticamente per essere mandati in esecuzione all'interno del processo stesso. Questi thread possono avere delle zone di memoria condivise ( possono essere delle variabili globali contenute nel data segment oppure dei file comuni). Se i thread dovessero solo leggere il dato / file non ci sarebbe nessun problema, ma se dovessero anche modificarlo?  Basti pensare al caso di un conto corrente:

Thread 1Thread 2Bilancio
Legge Bilancio: $1000$1000
Legge Bilancio: $1000$1000
Deposito $200$1000
Deposito $200$1000
Aggiorna Bilancio $1000+$200$1200
Aggiorna Bilancio $1000+$200$1200


Il primo thread legge il bilancio attuale (1000€) così come il secondo che esegue un deposito di 200€.
Viene eseguito un deposito da parte del primo thread, che va ad aggiornare il bilancio.
Il secondo thread non avrà il bilancio aggiornato (1200€) ma avrà il bilancio letto in precedenza (1000€), quindi quando si andrà ad aggiornare il valore si avrà solo l'ultima modifica fatta dal secondo thread e non quella fatta dal primo.
Questo esempio è uno dei tanti e fa capire quanto sia importante la gestione di thread o processi quando devono andare a scrivere su dei dati condivisi.

Per risolvere questo problema utilizziamo  le variabili mutex o le variabili semaforo.

Nella gestione di più processi o thread che eseguono delle corse critiche abbiamo 3 problemi ricorrenti, che sono i seguenti:
- Le cinque filosofe a tavola
- Il barbiere che dorme
- Lettore e scrittore
- Produttore e consumatore

Il primo problema è il seguente: 5 filosofe sono ad un tavolo rotondo per mangiare degli spaghetti. Ogni filosofa dispone di una sola forchetta ma sfortunatamente gli spaghetti sono così scivolosi che per mangiarli bisogna utilizzare per forza 2 forchette insieme.
Le nostre filosofe (cioè i nostri processi) possono essere in 3 stati distinti: pensante , affamata  e mangiante .
Come possiamo far mangiare il maggior numero di filosofe contemporaneamente senza creare nessuna situazione di stallo?

Utilizzeremo un vettore di interi state di un numero uguale a quello delle filosofe; in ognuno di queste posizioni andremo ad inserire lo stato della nostra filosofa (pensante, affamata e mangiante).
In totale avremo 6 mutex: 5 per ogni filosofa mentre ne avremo una globale.
Ogni filosofa può iniziare a mangiare solo se nessuna delle 2 filosofe ai suoi fianchi non sta mangiando.


Il codice per risolvere questo problema è il seguente:


#define N 5
#define THINKING 0
#define HUNGRY 1
#define EATING 2

typedef int semaphore;
int state[N];
semaphore Mutex=1; /*Master Mutex*/
semaphore S[N]; /*Philosopher's Mutex, Inizializzato come? tutto a zero, ovvero bloccato*/
/*down circa= lock. up circa= unlock. */

void philosopher(int i) //Codice eseguito dalle 5 filosofe
{
while (1)
{
think(); // La filosofa sta pensando
take_forks(i); // la filosofa è affamata, quindi cercherà di prendere le forchette
eat(); // entra nella sezione critica, inizia a mangiare
put_forks(i); // posa le forchette e ricomincia a pensare
}
}

void take_forks(int i)  //Funzione prendi forchette
{
down(&Mutex);  //Cerca di entrare nella zona critica
state[i]=HUNGRY; //Si modifica il suo stato rendendolo da pensante ad affamata
test(i); // controlla che le forchette siano disponibili, quindi che le due filosofe da parte non stiano mangiando
up(&Mutex); //Esce dalla regione critica
down(&S[i]); // Se la funzione test è andata a buon fine, quindi la filosofa ha ottenuto le forchette essa inizierà a mangiare, altrimenti si bloccherà aspettando che una delle filosofe ai suoi lati la sblocchi, così che possa iniziare a mangiare
}

void put_forks(int i) //Funzione posa forchette
{
down (&Mutex);  //Cerca di entrare nella zona critica
state[i]=THINKING; //Ha finito di mangiare, quindi il suo stato viene modificato in pensante
test( Left(i) ) ; // Controlla che la filosofa alla sua sinistra possa mangiare
test( Right(i) ); // Controlla che la filosofa alla sua destra possa mangiare
up(&Mutex); //Esce dalla regione critica
}

void test(i)  //Funzione che controlla che le filosofe possano iniziare a mangiare
{
if(state[i]== HUNGRY && state[ Left(i) ]!=EATING && state[ Right(i) ]!=EATING )
        //Se la filosofa è affamata e nessuna delle filosofe vicine sta mangiando, allora la filosofa può mangiare
{
state[i]=EATING; // Si mette nello stato mangiante
up(&S[i]); //fa una unlock sulla sua mutex, così che quando va a fare la down nella funzione take_forks(i) essa non verrà bloccata e quindi potrà mangiare
}
}

int Right(int i) /*Nome filosofa di destra*/
{
return (i-1) % N;
}

int Left(int i) /*Di sinistra */
{
return (i+1) % N;
}


Per riassumere.
Una filosofa quando smette di pensare sarà affamata, per poter mangiare dovrà avere le due filosofe ai fianchi che non stiano mangiando, altrimenti aspetterà fino a quando non saranno disponibili le forchette.
Il problema delle cinque filosofe è molto utile per risolvere problemi dove dei processi devono competere per l'accesso a un numero limitato di risorse, come i dispositivi di input/output.


Il secondo problema invece riguarda quello di un barbiere che ha una sola postazione per il taglio dei capelli e un numero di sedie per far attendere i clienti. Se non c'è nessun cliente nel negozio il barbiere inizierà a dormire. Quando arriverà un cliente si sveglierà e inizierà a tagliargli i capelli; se intanto arrivano altri clienti mentre il barbiere è occupato essi attenderanno sulle sedie, se un cliente vuole fare il taglio dei capelli ma ci sono tutte le sedie per attendere occupato questo se ne va.


Il codice è il seguente:

#define SEDIE 5 //Il numero di sedie utilizzate per far aspettare i clienti

typedef int semaforo; //La nostra variabile semaforo

semaforo clienti = 0;  //Numero dei clienti in attesa
semaforo barbieri = 0;  //Numero dei barbieri in attesa dei clienti
semaforo mutex = 1; //Mutex che utilizziamo per la mutua esclusione
int in_attesa = 0;  //Numero dei clienti in attesa (non durante il taglio dei capelli)

void barbiere(void)
{
     while(1)
     {
             down(&clienti); //Il barbiere inizierà a dormire se non c'è nessun cliente
             down(&mutex); //Entra nella sezione critica perché va a modificare una variabile globale ...
             in_attesa = in_attesa -1;  //... che è in_attesa
             up(&barbieri); //Un barbiere è pronto per tagliare i capelli al cliente
             up(&mutex); //Esco dalla zona critica
             taglia_capelli(); //Taglio i capelli al cliente
     }
}

void cliente(void)
{
     down(&mutex); //Entra nella zona critica
     if(in_attesa < SEDIE) //Se i clienti in attesa sono meno delle sedie per attendere...
     {
                  in_attesa = in_attesa +1;  //...anche questo cliente si metterà in attesa
                  up(&clienti); //Incrementa in numero di clienti in attesa
                  up(&mutex); //Esce dalla zona critica
                  down(&barbieri); //Blocca l'esecuzione del cliente se non c'è nessun barbiere disponibile per il taglio dei capelli
                  vai_al_taglio(); //Taglio dei capelli
     }
     else //Se tutte le sedie sono occupate
     {
         up(&mutex); // Allora esco direttamente dalla zona critica, senza eseguire il codice che mi serve
     }
}


Per fare un esempio, questo problema è ricorrente nei server web.
Ogni volta che un utente vorrà andare su una pagina web il server gli invierà il file .html della pagina corrispondente tramite un codice simile a quello del barbiere. Il server infatti avrà naturalmente più di un "barbiere" che potrà servire i vari utenti (perché se potesse inviare la pagina ad un solo utente alla volta sarebbe improponibile, basti pensare a pagine molto visitate) che richiedono la pagina internet; per gestire i più barbieri semplicemente li creerà come thread da un thread master. Il thread master sarà quello in ascolto sulla porta 80, cioè quella che riguarda le pagine web; ogni volta che un cliente arriva darà la richiesta del cliente al thread barbiere, rimettendosi immediatamente in ascolto per nuove richieste.