Difference between revisions of "Lezioni Anno Accademico 2017/18 I semestre"
Thomas.cup (talk | contribs) |
|||
Line 108: | Line 108: | ||
== Lezione del 3 ottobre 2017 == | == Lezione del 3 ottobre 2017 == | ||
+ | |||
+ | '''Introduzione alla programmazione concorrente: processi, thread e librerie''' | ||
− | ''' | + | Quando parliamo di ''sistema concorrente'', ci riferiamo ad un sistema in cui due o più "attori" sono eseguiti parallelamente.<br> |
+ | |||
+ | Questi attori possono essere '''processi''' o '''thread'''. | ||
+ | La differenza sostanziale tra queste due tipologie di attori riguarda la condivisione della memoria e dei dati su cui operano.<br> | ||
+ | |||
+ | Più processi possono eseguire lo stesso programma ma, ognuno di essi, ha i propri dati su cui operare e il suo stato di avanzamento.<br> | ||
+ | Più thread che vengono eseguiti parallelamente, invece, condividono gli stessi dati su cui operare.<br> | ||
+ | Codici di esempio: | ||
+ | |||
+ | '''processi''' | ||
+ | |||
+ | <syntaxhighlight lang=C> | ||
+ | #include <stdio.h> | ||
+ | #include <unistd.h> | ||
+ | |||
+ | int main(int argc, char *argv[]){ | ||
+ | if(fork()) printf("Yes"); | ||
+ | else printf("No"); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
== Lezione del 6 ottobre 2017 == | == Lezione del 6 ottobre 2017 == |
Revision as of 14:10, 4 October 2017
scrivete qui idee, riassunti dei concetti espressi, commenti approfondimenti sulle lezioni.
Lezione del 26 settembre 2017
Titolo della lezione: W⁴ H Y
- What:
- Who:
Noi studenti ed "entrambi" i professori.
- When:
Il corso ha durata annuale. Verrà svolto ogni martedì e venerdì dalle 15:30 alle 18:30.
- La lezione del martedì sarà dedicata alla programmazione concorrente;
- La lezione del venerdì sarà dedicata alla parte generale. Terminerà circa 15 minuti prima dell'orario stabilito.
- Where:
Sempre in Aula 1 Ercolani (E1): DISI, Scuole Ercolani, Mura Anteo Zamboni 2B.
- How:
Il corso si svolgerà tramite:
- Lezioni frontali in aula.
- Attività di laboratorio.
- Esercitazioni.
Inoltre, durante l'ultimo periodo di lezioni del secondo semestre, vi sarà un periodo di ripasso del programma tramite esercizi, in vista dell'esame.
Durante la lezione del 3/10 sono state indicate alcune propedeuticità del corso. tra cui: programmazione, algoritmi e architettura degli elaboratori in primis.
Importanti sono anche i corsi di Analisi matematica e Algebra e geometria. Per farla breve, il primo anno è propedeutico al secondo.
- Why:
- Fonti e strumenti del corso: wiki creata di gruppo, lezioni frontali e esercitazioni.
- Non esiste un vero e proprio testo consigliato. Tutte le informazioni sono date DURANTE il corso.
- Per domande specifiche scrivere su mailing list (so@cs.unibo.it);
- Per esercizi, appunti e programma svolto rivolgersi al wiki (so.v2.cs.unibo.it);
- Per live streaming (www.cs.unibo.it/~renzo/live/).
- Modalità di esame: esame scritto (diviso in due parti: una parte generale e una di programmazione concorrente) + progetto + orale (facoltativo), possibilità di dare solo lo scritto per ottenere un massimo di 18. La modalità per studenti in "difficoltà" è disponibile solo fino agli appelli autunnali.
- Si parlerà del progetto indicativamente a partire da Dicembre 2017.
- L'orale può essere sostenuto da chi vuole migliorare (peggiorare) il voto ottenuto, o da chi vuole ottenere la lode.
- Orario di ricevimento per il primo semestre (fino al 15/09/17): martedì alle 11:30.
- Università = docenti + studenti.
- Informatica = come generare informazione automatica.
- Hardware, Software, Elaborazione, Comunicazione, Memorizzazione, Digitale/Analogico.
La principale distinzione che facciamo tra dato e informazione è che il dato, da solo, è privo di significato. Se, tuttavia, viene interpretato in un particolare contesto allora può diventare informazione significativa per chi sta interpretando i dati.
Un algoritmo è una o più sequenze non ambigue di passi che, dato un problema, ci permette di risolverlo.
Il nostro algoritmo, scritto in un qualche linguaggio formale, diventa un programma (sostanzialmente un testo, un insieme di istruzioni).
Un linguaggio è un entità software, ed è definito come una quadrupla (alfabeto, sintassi, lessico, semantica) dove:
- l'alfabeto è l'insieme di simboli che compone il linguaggio.
- il lessico si può vedere come una funzione che va dai simboli a un booleano e ci dice quali sono le frasi ben formate.
- la sintassi determina quali delle sequenze scritte sono effettivamente corrette.
- la semantica associa un significato alle parole ben formate.
Lezione del 29 settembre 2017
Cos'è un sistema operativo e un po' di storia
Un sistema operativo è un programma che gestisce i processi, le risorse e interfaccia le applicazioni con l'hardware dell'elaboratore.
In particolare, il sistema operativo (laddove esiste) è il primo processo ad essere attivato e resta in vita fino allo spegnimento del calcolatore o al sopraggiungere di un errore fatale per il sistema.
A cosa serve un sistema operativo? Principalmente, ha i seguenti scopi:
- Facilitare l'utilizzo del sistema (senza S.O. sarebbe a carico del programmatore conoscere tutti i linguaggi con cui si comunica con l'architettura della macchina);
- Rendere affidabile, protetto e sicuro l'utilizzo del sistema (e.g. un processo potrebbe recar danno all'intero sistema se non controllato o gestito, potrebbe ignorare i permessi di visualizzazione di un file);
- Astrarre l'hardware (e.g. filesystem);
- Garantire l'efficienza (e.g. non tenere la CPU in idle adottando opportuni algoritmi di scheduling);
- Assicurare portabilità ;
Un approccio molto usato è il cosiddetto approccio a strati ("a livelli") in cui ogni strato utilizza i servizi forniti al livello inferiore e ne fornisce di nuovi a quello superiore. Astraendo il nostro calcolatore possiamo piazzare al livello più basso l'hardware e, subito sopra, il sistema operativo. I due layer comunicano usando il linguaggio ISA (Instruction Set Architecture), nativo della CPU stessa, al quale si aggiungono quelli che permettono di comunicare con i vari controllori dei dispositivi come la scheda di rete, la stampante, etc. Sopra il livello del sistema operativo possiamo collocare quello delle librerie e, infine, quello degli applicativi.
- Systemcall = meccanismo usato da un processo per richiedere al SO una qualche funzionalità a livello kernel. Un esempio è la funzione printf() del linguaggio C (stampa a video) che utilizza la systemcall write() (una delle systemcall per la gestione dei dispositivi).
Storia dei sistemi operativi
Nella generazione zero (1800 ca.) possiamo includere Babbage con la sua macchina analitica e lady Ada Lovelace.
Nella generazione uno vediamo la comparsa delle valvole con tutti i problemi connessi. Non c'erano utilizzatori delle macchine, le stesse persone che le costruivano erano anche programmatori e fruitori delle stesse.
Nella generazione due (fine anni '60) arriva il transistor. Quest'ultimo è molto più veloce e piccolo della valvola e, soprattutto, meno incline a guasti. Le macchine iniziano ad essere più economiche grazie alla possibilità di avere un'economia di scala e quindi accessibili al grande pubblico. Questo fa si che, in queste prime fasi, i costruttori non siano più gli unici utilizzatori.
A questo punto poiché, pur essendo diventata più accessibile, una macchina costava ancora molto, nasce l'esigenza di non lasciare mai un processore senza lavoro (al fine di massimizzare i ricavi) e di condividere i dati. In questa fase, infatti, abbiamo sistemi operativi di tipo batch (che collezionano tutto l'input all'inizio per calcolare e restituire l'output) dove l'inserimento di programmi e dati veniva fatto tramite schede perforate e non c'era interazione. Dai sistemi batch nasce lo SPOOL (Simultaneous Peripheral Operations On-Line).
Si comincia a pensare di utilizzare i tempi di I/O per poter eseguire altri processi. Questo però solleva almeno due problematiche: da un lato serve un modo per sapere quando un input è davvero finito mentre, dall'altro, bisogna fare in modo che un processo che non richieda I/O non occupi la CPU per un tempo indefinito. Per la prima problematica la soluzione è rappresentata dall'introduzione degli interrupt, segnali elettrici inviati alla CPU alla fine di ogni input. Per la seconda, invece, è stato introdotto il cosiddetto interval timer che non è altro che un dispositivo che invia interrupt dopo un determinato quanto di tempo assicurando che un processo non occupi per troppo tempo il processore. Questo consente di realizzare sistemi time sharing (il cui più semplice algoritmo è il round-robin) dove un processo può essere in uno dei seguenti tre stati:
- READY pronto per essere eseguito ma, il processore è già occupato;
- RUNNING in esecuzione;
- WAIT in attesa di I/O.
Nella quarta generazione (anni '70 ca.) vediamo la nascita di molte innovazioni importanti. Si riesce a rimpicciolire di molto i processori facendoli divenire a tutti gli effetti micro-processori. Nei laboratori Bell nasce Unix, un sistema operativo rivoluzionario con time sharing e clonazione dei processi (un processo non viene mai creato dal nulla ma viene prima clonato da uno già esistente e poi, alla copia, viene fatto eseguire un programma). A causa di problemi di portabilità da PDP-9, macchina su cui Unix è nato, a PDP-11 nasce il linguaggio C e il suo compilatore (scritto anch'esso in C). Mentre Apple I "porta" una nuova idea di pc per tutte le famiglie, nascono molte versioni di Unix. Per impedire una deriva proprietaria in cui ogni produttore offriva tutto quello che offrivano gli altri ma con qualche feature in più, Richard Stallman fonda il progetto GNU (GNU's Not Unix) per il quale scrive tutta una serie di utilities come il famoso compilatore gcc. A GNU, per essere operativo, manca però un kernel. Non volendo aspettare i tempi di sviluppo del kernel che Stallman aveva in mente, Linus Torlvalds scrive il kernel Linux da cui nasce il sistema operativo GNU/Linux.
Nei tempi più recenti nascono i processori multi-core.
Lezione del 3 ottobre 2017
Introduzione alla programmazione concorrente: processi, thread e librerie
Quando parliamo di sistema concorrente, ci riferiamo ad un sistema in cui due o più "attori" sono eseguiti parallelamente.
Questi attori possono essere processi o thread.
La differenza sostanziale tra queste due tipologie di attori riguarda la condivisione della memoria e dei dati su cui operano.
Più processi possono eseguire lo stesso programma ma, ognuno di essi, ha i propri dati su cui operare e il suo stato di avanzamento.
Più thread che vengono eseguiti parallelamente, invece, condividono gli stessi dati su cui operare.
Codici di esempio:
processi
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[]){
if(fork()) printf("Yes");
else printf("No");
}