Changes between Version 35 and Version 36 of WikiStart


Ignore:
Timestamp:
May 9, 2009, 4:33:38 PM (11 years ago)
Author:
monga
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • WikiStart

    v35 v36  
    1313=== Programmi ===
    1414
    15  * Accesso diretto alla macchina fisica source:trunk/mioboot-nobios-simple.asm
    16  * Uso dei servizi del BIOS source:trunk/mioboot.asm
     15 * Accesso diretto alla macchina fisica export:trunk/mioboot-nobios-simple.asm
     16   [[IncludeSource(trunk/mioboot-nobios-simple.asm, line_numbers=0)]]
     17
     18 * Uso dei servizi del BIOS export:trunk/mioboot.asm
     19   [[IncludeSource(trunk/mioboot.asm, line_numbers=0)]]
    1720
    1821{{{
     
    2326}}}
    2427
    25  * Programma che esegue il codice letto da standard input exec.c
    26 {{{
    27 #!c
    28 #include <stdio.h>
    29 
    30 int main() {
    31   unsigned char buf[1024];
    32   void (*ptr)();
    33   int n;
    34   unsigned int eax;
    35 
    36   // leggi il codice da eseguire da standard input
    37   n = read(0, buf, 1024);
    38   // forza il codice a ritornare dalla chiamata a funzione (0xC3 = ret)
    39   buf[n] = '\xc3';
    40 
    41   // esegui il codice letto come se fosse una funzione
    42   ptr = (void(*)()) buf;
    43   ptr();
    44 
    45   // stampa il valore del registro EAX
    46   __asm__("mov %%eax, %0" : "=m"(eax));
    47   printf("EAX: %.8x\n", eax);
    48 
    49   return 0;
    50 }
    51 }}}
     28 * Programma che esegue il codice letto da standard input export:trunk/exec.c
     29  [[IncludeSource(trunk/exec.c, line_numbers=0)]]
     30
     31
    5232{{{
    5333gcc -o exec exec.c
     
    6444 * [http://fabrice.bellard.free.fr/qemu_0.10.0-1_i386.deb QEmu]
    6545   * [http://homes.dico.unimi.it/sisop/qemu-0.9.0-win32.zip QEmu 0.9.0 per windows]
    66    * [http://homes.dico.unimi.it/sisop/qemu_0.10.0-1_i386.deb QEmu 0.10 per Linux (Debian & Ubuntu)]
     46   * [http://www.coresystems.de/%7Epatrick/qemu-0.10.0-bin.zip QEmu 0.10.1 per Windows]
     47   * [http://homes.dico.unimi.it/sisop/qemu_0.10.0-1_i386.deb QEmu 0.10.1 per Linux (Debian & Ubuntu)]
     48   * [http://www.puredarwin.org/downloads/qemu-0.10.1.dmg QEmu 0.10.1 per Mac OS X]
    6749 * [http://homes.dico.unimi.it/~sisop/qemu/minix3-full.qcow Immagine Qemu MINIX 3.1.2a con Vim, ssh, ecc.]
    6850
     
    8062 ==== {{{fork}}} ====
    8163
    82 {{{
    83 #!c
    84 /* un programma che "forca" un nuovo processo */
    85 
    86 #include <unistd.h>
    87 #include <stdio.h>
    88 #include <stdlib.h>
    89 
    90 int main(void){
    91   int x = fork();
    92   if (x < 0){
    93       perror("Errore nella fork:");
    94       exit(1);
    95   } else {
    96     if (x != 0){
    97       while(1){
    98         sleep(1);
    99         printf("Processo padre (Figlio: %d)\n", x);
    100       }
    101     } else {
    102       while(1) {
    103        printf("Processo figlio (%d)\n", x);
    104        sleep(1);
    105       }
    106     }
    107   }
    108   return 0;
    109 }
    110 
    111 /* da compilare con un comando del tipo 'cc -o prova prova.c' */
    112 /* Per terminare Ctrl-C */
    113 }}}
    114 
    115 ==== Exit status ====
    116 {{{
    117 #!c
    118 #include <stdio.h>
    119 #include <stdlib.h>
    120 
    121 int main(int argc, char **argv) {
    122   int i;
    123 
    124   if (argc != 2)
    125     return -1;
    126 
    127   return atoi(argv[1]);
    128 }
    129 
    130 /* da compilare con un comando del tipo 'cc -o prova prova.c' */
    131 /* Per verificare l'exit status: ./prova ; echo $? */
    132 }}}
    133 
    134 ==== Esecuzione in sequenza e parallelo ====
    135 
    136 {{{
    137 #!c
    138 #include <stdio.h>
    139 #include <unistd.h>
    140 
    141 int main(void){
    142   int i = 0;
    143   for (i=0; i<10; ++i){
    144     sleep(1);
    145     printf("%d: %d\n", getpid(), i);
    146   }
    147   return 0;
    148 }
    149 }}}
     64 * un programma che "forca" un nuovo processo export:trunk/fork.c
     65   [[IncludeSource(trunk/fork.c, line_numbers=0)]]
     66
     67 * exit status export:trunk/exit.c
     68   [[IncludeSource(trunk/exit.c, line_numbers=0)]]
     69
     70
     71 ==== Esecuzione in sequenza e parallelo ====
     72
     73 * programma di prova export:trunk/hello.c
     74   [[IncludeSource(trunk/hello.c, line_numbers=0)]]
     75
     76
    15077
    15178{{{
     
    212139 * [UnixShell UNIX Shell: kit di sopravvivenza (in aggiornamento)]
    213140
    214 ==== stdout.c ====
    215 
    216 {{{
    217 #!c
    218 /*
    219    scrive st stdout(1) gli argomenti ricevuti sulla riga di comando
    220 
    221    utile per capire come funzionano quoting, escaping e command substitution nella shell:
    222    e.s. ./stdout "ciao ciao"
    223         ./stdout ciao ciao
    224         a="giallo"; b="rosso" ; ./stdout "$a $b"
    225         ./stdout $(ls /etc)
    226 
    227    compilare con: cc -o stdout stdout.c
    228 
    229 */
    230 
    231 #include <stdio.h>
    232 
    233 int main(int argc, char **argv) {
    234   int i;
    235 
    236   for (i = 0; i < argc; i++) {
    237     printf("%d: %s\n", i, argv[i]);
    238   }
    239 
    240   return 0;
    241 }
    242 }}}
    243 
    244 ==== stdouterr.c ====
    245 
    246 {{{
    247 #!c
    248 
    249 /*
    250    scrive su stdout(1)  e stderr (2) gli argomenti ricevuti sulla riga di
    251    comando; l'i-esimo argomento viene scritto su stdout se i e' pari e su
    252    stderr se i e' dispari
    253    
    254    utile per capire come funzionano redirezione e pipe nella shell
    255    e.s. ./stdouterr "primo argomento" "secondo argomento" | cat
    256         ./stdouterr "primo argomento" "secondo argomento" 2> /tmp/2
    257         ./stdouterr "primo" "secondo" 2> /dev/null
    258 
    259    per compilare: cc -o stdouterr stdouterr.c
    260 */
    261 
    262 #include <stdio.h>
    263 #include <string.h>
    264 
    265 int main(int argc, char **argv) {
    266   int i;
    267   char buf[2048];
    268 
    269   for (i = 0; i < argc; i++) {
    270     snprintf(buf, 2047, "%d: %s\n", i, argv[i]);
    271     write(i % 2 + 1, buf, strlen(buf));
    272   }
    273 
    274   return 0;
    275 }
    276 
    277 }}}
    278 
     141 * scrive su stdout(1) gli argomenti ricevuti sulla riga di comando export:trunk/stdout.c
     142   [[IncludeSource(trunk/stdout.c, line_numbers=0)]]
     143
     144 * scrive su stdout(1)e stderr (2) gli argomenti ricevuti sulla riga di comando export:trunk/stdouterr.c
     145   [[IncludeSource(trunk/stdouterr.c, line_numbers=0)]]
    279146
    280147=== Esercizi online con la shell ===
     
    292159==== Esempi con la syscall `clone`, specifica di Linux ====
    293160
    294  * Thread '''senza''' memoria condivisa  `threads-isolated.c`
     161 * Thread '''senza''' memoria condivisa  export:trunk/threads-isolated.c
     162   [[IncludeSource(trunk/threads-isolated.c, line_numbers=0)]]
     163
     164 * Thread '''con''' memoria condivisa export:trunk/threads-shared.c
     165   [[IncludeSource(trunk/threads-shared.c, line_numbers=0)]]
     166
     167 * Thread '''con''' memoria condivisa, mutua esclusione ottenuta con Peterson export:trunk/threads-peterson.c
     168   [[IncludeSource(trunk/threads-peterson.c, line_numbers=0)]]
     169
     170 * Thread '''con''' memoria condivisa, mutua esclusione con TSL export:trunk/threads-tsl.c export:trunk/enter.asm
     171   [[IncludeSource(trunk/threads-tsl.c, line_numbers=0)]]
     172   [[IncludeSource(trunk/enter.asm, line_numbers=0)]]
    295173 
    296 {{{
    297 #!c
    298 #include <unistd.h>
    299 #include <stdio.h>
    300 #include <stdlib.h>
    301 #include <signal.h>
    302 #include <sched.h>
    303 
    304 int run(void* s)
    305 {
    306         int* shared = (int*)s; /* alias per comodita` */
    307         while (shared[0] < 10) {
    308                 sleep(1);
    309                 printf("Processo figlio (%d). s = %d\n",
    310                        getpid(), shared[0]);
    311                 if (!(shared[0] < 10)){
    312                         printf("Corsa critica!!!!\n");
    313                         abort();
    314                 }
    315                 shared[0] += 1;
    316         }
    317         return 0;
    318 }
    319 
    320 
    321 int main(void){
    322  
    323         int shared[2] = {0 , 0};
    324 
    325         /* int clone(int (*fn)(void *),
    326          *           void *child_stack,
    327          *           int flags,
    328          *           void *arg);
    329          * crea una copia del chiamante (con le caratteristiche
    330          * specificate da flags) e lo esegue partendo da fn */
    331         if (clone(run, /* il nuovo
    332                         * processo esegue run(shared), vedi quarto
    333                         * parametro */
    334                   malloc(4096)+4096,  /* lo stack del nuovo processo
    335                                        *  (cresce verso il basso!) */
    336                   SIGCHLD, /* in questo caso la clone e` analoga alla fork */
    337                   shared) < 0){
    338                 perror("Errore nella creazione");
    339                 exit(1);
    340         }
    341 
    342         if (clone(run, malloc(4096)+4096,  SIGCHLD, shared) < 0){
    343                 perror("Errore nella creazione");
    344                 exit(1);
    345         }
    346 
    347         /* Isolati: ciascuno dei figli esegue 10 volte. Per il padre
    348          * shared[0] e` sempre 0 */
    349 
    350         while(1) {
    351                 sleep(1);
    352                 printf("Processo padre. s = %d\n", shared[0]);
    353         }
    354         return 0;
    355 }
    356 }}}
    357 
    358  * Thread '''con''' memoria condivisa `threads-shared.c`
    359 
    360 {{{
    361 #!c
    362 #include <unistd.h>
    363 #include <stdio.h>
    364 #include <stdlib.h>
    365 #include <signal.h>
    366 #include <sched.h>
    367 
    368 int run(void* s)
    369 {
    370         int* shared = (int*)s; /* alias per comodita` */
    371         while (shared[0] < 10) {
    372                 sleep(1);
    373                 printf("Processo figlio (%d). s = %d\n",
    374                        getpid(), shared[0]);
    375                 if (!(shared[0] < 10)){
    376                         printf("Corsa critica!!!!\n");
    377                         abort();
    378                 }
    379                 shared[0] += 1;
    380         }
    381         return 0;
    382 }
    383 
    384 
    385 int main(void){
    386  
    387         int shared[2] = {0 , 0};
    388 
    389         /* int clone(int (*fn)(void *),
    390          *           void *child_stack,
    391          *           int flags,
    392          *           void *arg);
    393          * crea una copia del chiamante (con le caratteristiche
    394          * specificate da flags) e lo esegue partendo da fn */
    395         if (clone(run, /* il nuovo
    396                         * processo esegue run(shared), vedi quarto
    397                         * parametro */
    398                   malloc(4096)+4096,  /* lo stack del nuovo processo
    399                                        *  (cresce verso il basso!) */
    400                   CLONE_VM | SIGCHLD, /* la (virtual) memory e` condivisa */
    401                   shared) < 0){
    402                 perror("Errore nella creazione");
    403                 exit(1);
    404         }
    405 
    406         if (clone(run, malloc(4096)+4096,  CLONE_VM | SIGCHLD, shared) < 0){
    407                 perror("Errore nella creazione");
    408                 exit(1);
    409         }
    410 
    411         /* Memoria condivisa: i due figli nell'insieme eseguono 10 o
    412          * 11 volte: e` possibile una corsa critica. Il padre
    413          * condivide shared[0] con i figli */
    414 
    415         while(1) {
    416                 sleep(1);
    417                 printf("Processo padre. s = %d\n", shared[0]);
    418         }
    419         return 0;
    420 }
    421 }}}
    422 
    423  * Thread '''con''' memoria condivisa, mutua esclusione ottenuta con Peterson `threads-peterson.c`
    424 
    425 {{{
    426 #!c
    427 #include <unistd.h>
    428 #include <stdio.h>
    429 #include <stdlib.h>
    430 #include <signal.h>
    431 #include <sched.h>
    432 
    433 
    434 void enter_section(int process, int* turn, int* interested)
    435 {
    436         int other = 1 - process;
    437         interested[process] = 1;
    438         *turn = process;
    439         while  (*turn == process && interested[other]){
    440                 printf("Busy waiting di %d\n", process);
    441         }
    442 }
    443 
    444 void leave_section(int process, int* interested)
    445 {
    446         interested[process] = 0;
    447 }
    448 
    449 int run(const int p, void* s)
    450 {
    451         int* shared = (int*)s; /* alias per comodita` */
    452         while (enter_section(p, &shared[1], &shared[2]),
    453                shared[0] < 10) {
    454                 sleep(1);
    455                 printf("Processo figlio (%d). s = %d\n",
    456                        getpid(), shared[0]);
    457                 if (!(shared[0] < 10)){
    458                         printf("Corsa critica!!!!\n");
    459                         abort();
    460                 }
    461                 shared[0] += 1;
    462                 leave_section(p, &shared[2]);
    463         }
    464         return 0;
    465 }
    466 }}}
    467 
    468  * Thread '''con''' memoria condivisa, mutua esclusione con TSL `threads-tsl.c`, `enter.asm`
    469 
    470 {{{
    471 #!c
    472 #include <unistd.h>
    473 #include <stdio.h>
    474 #include <stdlib.h>
    475 #include <signal.h>
    476 #include <sched.h>
    477 
    478 
    479 void enter_section(int *s); /* in enter.asm */
    480 
    481 void leave_section(int *s){
    482         *s = 0;
    483 }
    484 
    485 int run(const int p, void* s)
    486 {
    487         int* shared = (int*)s; /* alias per comodita` */
    488         while (enter_section(&shared[1]),
    489                shared[0] < 10) {
    490                 sleep(rand() % 3);
    491                 printf("Processo figlio (%d). s = %d\n",
    492                        getpid(), shared[0]);
    493                 if (!(shared[0] < 10)){
    494                         printf("Corsa critica!!!!\n");
    495                         abort();
    496                 }
    497                 shared[0] += 1;
    498                 leave_section(&shared[1]);
    499         }
    500         return 0;
    501 }
    502 
    503 int run0(void*s){ return run(0, s); }
    504 int run1(void*s){ return run(1, s); }
    505        
    506 
    507 int main(void){
    508  
    509         int shared[4] = {0 , 0, 0, 0};
    510 
    511         /* int clone(int (*fn)(void *),
    512          *           void *child_stack,
    513          *           int flags,
    514          *           void *arg);
    515          * crea una copia del chiamante (con le caratteristiche
    516          * specificate da flags) e lo esegue partendo da fn */
    517         if (clone(run0, /* il nuovo
    518                          * processo esegue run(shared), vedi quarto
    519                          * parametro */
    520                   malloc(4096)+4096,  /* lo stack del nuovo processo
    521                                        *  (cresce verso il basso!) */
    522                   CLONE_VM | SIGCHLD, /* la (virtual) memory e` condivisa */
    523                   shared) < 0){
    524                 perror("Errore nella creazione");
    525                 exit(1);
    526         }
    527 
    528         if (clone(run1, malloc(4096)+4096,  CLONE_VM | SIGCHLD, shared) < 0){
    529                 perror("Errore nella creazione");
    530                 exit(1);
    531         }
    532 
    533         /* Memoria condivisa: i due figli nell'insieme eseguono 10 o
    534          * 11 volte: e` possibile una corsa critica. Il padre
    535          * condivide shared[0] con i figli */
    536 
    537         while(shared[0] < 10) {
    538                 sleep(1);
    539                 printf("Processo padre. s = %d %d %d %d\n",
    540                        shared[0],
    541                        shared[1],
    542                        shared[2],
    543                        shared[3]);
    544         }
    545         return 0;
    546 }
    547 }}}
    548 
    549 {{{
    550 section .text
    551 global enter_section
    552 
    553 enter_section:
    554         enter 0, 0         ; 0 bytes of local stack space
    555         mov   ebx,[ebp+8]     ; first parameter to function
    556 
    557 spin:   lock bts dword [ebx], 0
    558         jc spin
    559 
    560         leave                   ; mov esp,ebp / pop ebp
    561         ret     
    562 }}}
    563 
    564174{{{
    565175#!sh
     
    568178}}}
    569179
    570  * Thread '''con''' memoria condivisa, mutua esclusione ottenuta con semaforo `threads-sem.c`
    571 
    572 {{{
    573 #!c
    574 #include <unistd.h>
    575 #include <stdio.h>
    576 #include <stdlib.h>
    577 #include <signal.h>
    578 #include <sched.h>
    579 #include <semaphore.h>
    580 
    581 sem_t S;
    582 
    583 void enter_section(){
    584    if (sem_wait(&S) < 0){
    585        perror("Errore semaforo (down)");
    586        exit(1);
    587    }
    588 }
    589 
    590        
    591 
    592 void leave_section()
    593 {
    594         if (sem_post(&S) < 0){
    595                 perror("Errore semaforo (up)");
    596                 exit(1);
    597         }
    598 }
    599 
    600 int run(const int p, void* s)
    601 {
    602         int* shared = (int*) s;
    603         while (enter_section(),
    604                *shared < 10) {
    605                 printf("Processo figlio (%d). s = %d\n",
    606                        getpid(), *shared);
    607                 sleep(1);
    608                 if (!(*shared < 10)){
    609                         printf("Corsa critica!!!!\n");
    610                         abort();
    611                 }
    612                 *shared += 1;
    613                 leave_section();
    614                 sched_yield();
    615         }
    616         return 0;
    617 }
    618 
    619 int main(void){
     180 * Thread '''con''' memoria condivisa, mutua esclusione ottenuta con semaforo export:trunk/threads-sem.c
     181   [[IncludeSource(trunk/threads-sem.c, line_numbers=0)]]
    620182 
    621         int shared = 0;
    622 
    623         if (sem_init(&S,
    624                      0 /* thread local semaphore */,
    625                      1 /* init value */
    626                     ) < 0){
    627                 perror("Errore semaforo");
    628                 exit(1);
    629         }
    630 
    631         /* int clone(int (*fn)(void *),
    632          *           void *child_stack,
    633          *           int flags,
    634          *           void *arg);
    635          * crea una copia del chiamante (con le caratteristiche
    636          * specificate da flags) e lo esegue partendo da fn */
    637         if (clone(run, /* il nuovo
    638                          * processo esegue run(shared), vedi quarto
    639                          * parametro */
    640                   malloc(4096)+4096,  /* lo stack del nuovo processo
    641                                        *  (cresce verso il basso!) */
    642                   CLONE_VM | SIGCHLD, /* la (virtual) memory e` condivisa */
    643                   &shared) < 0){
    644                 perror("Errore nella creazione");
    645                 exit(1);
    646         }
    647 
    648         if (clone(run, malloc(4096)+4096,  CLONE_VM | SIGCHLD, &shared) < 0){
    649                 perror("Errore nella creazione");
    650                 exit(1);
    651         }
    652 
    653         while(shared < 10) {
    654                 sleep(1);
    655                 printf("Processo padre. s = %d\n", shared);
    656         }
    657 
    658         sem_destroy(&S);
    659         return 0;
    660 }
    661 }}}
    662 
    663183{{{
    664184#!sh
     
    669189==== Esempi in Java ====
    670190
    671  * Creazione di thread `Basic.java`
    672 
    673 {{{
    674 #!java
    675 class ClasseAttiva extends Thread{
    676     public void run(){
    677         while (true) {
    678             try {
    679                 Thread.sleep(100);
    680             }
    681             catch(InterruptedException e){
    682                 System.err.println(e);
    683             }
    684             System.out.println(this.getName());
    685         }
    686     }
    687 }
    688 
    689 public class Basic {
    690     public static final void main(final String[] args) {
    691         ClasseAttiva o1 = new ClasseAttiva();
    692         ClasseAttiva o2 = new ClasseAttiva();
    693         o1.start();
    694         o2.start();
    695         while (true){
    696             try {
    697                 Thread.sleep(100);
    698             }
    699             catch(InterruptedException e){
    700                 System.err.println(e);
    701             }
    702 
    703             System.out.println("Main thread");
    704         }
    705        
    706     }
    707 }
    708 }}}
    709 
    710  * Memoria condivisa `Shared.java`
    711 
    712 {{{
    713 #!java
    714 
    715 class ClasseAttiva extends Thread{
    716     protected static int shared = 0;
    717     public void run() {
    718         while (true) {
    719             if (shared >= 10) break;
    720             try {
    721                 Thread.sleep(1000);
    722             }
    723             catch(InterruptedException e){
    724                 System.err.println(e);
    725             }
    726             if (shared >= 10){
    727                 throw new Error("Corsa critica!!!");
    728             }
    729             System.out.println(this.getName() + " s = " + shared);
    730             shared += 1;
    731         }
    732     }
    733 }
    734 
    735 
    736 
    737 public class Shared {
    738     public static final void main(final String[] args) {
    739         ClasseAttiva o1 = new ClasseAttiva();
    740         ClasseAttiva o2 = new ClasseAttiva();
    741         o1.start();
    742         o2.start();
    743         while (true){
    744             try {
    745                 Thread.sleep(1000);
    746             }
    747             catch(InterruptedException e){
    748                 System.err.println(e);
    749             }
    750 
    751             System.out.println("Main thread");
    752         }
    753        
    754     }
    755 }
    756 }}}
    757 
    758  * Memoria condivisa, mutua esclusione ottenuta con `synchronized`, `Shared2.java`
    759 
    760 {{{
    761 #!java
    762 class ClasseAttiva extends Thread{
    763     protected static int shared = 0;
    764     protected static Object lock = new Object();
    765     public void run() {
    766         while (true) {
    767             synchronized(lock){
    768                 if (shared >= 10) break;
    769                 try {
    770                     Thread.sleep(1000);
    771                 }
    772                 catch(InterruptedException e){
    773                     System.err.println(e);
    774                 }
    775                 if (shared >= 10){
    776                     throw new Error("Corsa critica!!!");
    777                 }
    778                 System.out.println(this.getName() + " s = " + shared);
    779                 shared += 1;
    780             }
    781             Thread.yield(); // non necessaria, ma favorisce lo scheduling di entrambi
    782         }
    783     }
    784 }
    785 
    786 
    787 
    788 public class Shared2 {
    789     public static final void main(final String[] args) {
    790         ClasseAttiva o1 = new ClasseAttiva();
    791         ClasseAttiva o2 = new ClasseAttiva();
    792         o1.start();
    793         o2.start();
    794         while (true){
    795             try {
    796                 Thread.sleep(1000);
    797             }
    798             catch(InterruptedException e){
    799                 System.err.println(e);
    800             }
    801 
    802             System.out.println("Main thread");
    803         }
    804        
    805     }
    806 }
    807 }}}
    808 
    809  * Produttore e consumatore
    810 
    811 {{{
    812 #!java
    813 
    814 class Actor extends Thread
    815 {
    816     public Actor(String nome){
    817         super(nome);
    818     }
    819    
    820     private Magazzino shared;
    821     public final Magazzino getShared() {
    822         return shared;
    823     }
    824     public final void setShared(final Magazzino newShared) {
    825         this.shared = newShared;
    826     }
    827 
    828 }
    829 
    830 
    831 class Produttore extends Actor {
    832     public Produttore(String nome, Magazzino b) {
    833         super(nome);
    834         setShared(b);
    835     }
    836    
    837     public void run(){
    838         int i = 0;
    839         while(true){
    840             System.out.println(getName() + ": Inserisco " + i + " nel buffer");
    841             getShared().put(i);
    842             i += 1;
    843         }
    844     }
    845 }
    846 
    847 class Consumatore extends Actor{
    848     public Consumatore(String nome, Magazzino b) {
    849         super(nome);
    850         setShared(b);
    851     }
    852     public void run(){
    853         while(true){
    854             int i = getShared().get();
    855             System.out.println(getName() + ": Estraggo " + i + " dal buffer");
    856 
    857         }
    858     }
    859 }
    860 
    861 class Magazzino{
    862     public final static int SIZE = 10;
    863     private int[] memory = new int[SIZE];
    864     private int quanti = 0;
    865 
    866     public final int get() {
    867         String n = Thread.currentThread().getName();
    868         synchronized(syncPC){
    869             while(isVuoto()){
    870                 System.out.println(n + " ha tentato di leggere");
    871                 try {
    872                     syncPC.wait();
    873                 } catch (InterruptedException e) {
    874                     System.err.println(e);
    875                 }
    876             }
    877             int ris = memory[--quanti];
    878             if (quanti == SIZE - 1) syncPC.notifyAll();
    879             System.out.println(n + " ha letto");
    880             return ris;
    881         }
    882     }
    883 
    884     public final void put(final int newMemory) {
    885         String n = Thread.currentThread().getName();
    886         synchronized(syncPC){
    887             while (isPieno()){
    888                 System.out.println(n + " ha tentato di scrivere");
    889                 try {
    890                     syncPC.wait();
    891                 } catch (InterruptedException e) {
    892                     e.printStackTrace(System.err);
    893                 }
    894             }
    895             memory[quanti++] = newMemory;
    896             if (quanti == 1) syncPC.notifyAll();
    897             System.out.println(n + " ha scritto");
    898         }
    899     }
    900 
    901     public final boolean isVuoto() {
    902         return quanti == 0;
    903     }
    904 
    905     public final boolean isPieno() {
    906         return quanti == SIZE;
    907     }
    908 
    909     private Object syncPC = new Object();
    910 }
    911 
    912 
    913 public class PC {
    914 
    915     public static final void main(final String[] args) {
    916         Magazzino x = new Magazzino();
    917         Produttore a1 = new Produttore("Aldo", x);
    918         Produttore a2 = new Produttore("Alberto", x);
    919         Consumatore b = new Consumatore("Barbara", x);
    920         a1.start();
    921         b.start();
    922         a2.start();
    923     }
    924 
    925 }
    926 }}}
    927 
    928 
    929  * Produttore e consumatore con semafori `PCSem.java`
    930 
    931 {{{
    932 #!java
    933 import java.util.concurrent.Semaphore;
    934 
    935 class Actor extends Thread
    936 {
    937     public Actor(String nome){
    938         super(nome);
    939     }
    940    
    941     private Magazzino shared;
    942     public final Magazzino getShared() {
    943         return shared;
    944     }
    945     public final void setShared(final Magazzino newShared) {
    946         this.shared = newShared;
    947     }
    948 
    949 }
    950 
    951 
    952 class Produttore extends Actor {
    953     public Produttore(String nome, Magazzino b) {
    954         super(nome);
    955         setShared(b);
    956     }
    957    
    958     public void run(){
    959         int i = 0;
    960         while(true){
    961             System.out.println(getName() + ": Inserisco " + i + " nel buffer");
    962             getShared().put(i);
    963             i += 1;
    964         }
    965     }
    966 }
    967 
    968 class Consumatore extends Actor{
    969     public Consumatore(String nome, Magazzino b) {
    970         super(nome);
    971         setShared(b);
    972     }
    973     public void run(){
    974         while(true){
    975             int i = getShared().get();
    976             System.out.println(getName() + ": Estraggo " + i + " dal buffer");
    977 
    978         }
    979     }
    980 }
    981 
    982 class Magazzino{
    983     public final static int SIZE = 10;
    984     private int[] memory = new int[SIZE];
    985     private int quanti = 0;
    986    
    987     public final int get() {
    988         try{
    989             String n = Thread.currentThread().getName();
    990             pieno.acquire();
    991             mutex.acquire();
    992             int ris = memory[--quanti];
    993             mutex.release();
    994             vuoto.release();
    995        
    996             System.out.println(n + " ha letto");
    997             return ris;
    998         }
    999         catch(InterruptedException e){
    1000             System.err.println(e);
    1001             return -1;
    1002         }
    1003     }
    1004 
    1005     public final void put(final int newMemory) {
    1006         try{
    1007             String n = Thread.currentThread().getName();
    1008             vuoto.acquire();
    1009             mutex.acquire();
    1010             memory[quanti++] = newMemory;
    1011             mutex.release();
    1012             pieno.release();
    1013             System.out.println(n + " ha scritto");
    1014         }
    1015         catch(InterruptedException e){
    1016             System.err.println(e);
    1017         }
    1018     }
    1019 
    1020     private static final Semaphore mutex = new Semaphore(1);
    1021     private static final Semaphore pieno = new Semaphore(0);
    1022     private static final Semaphore vuoto = new Semaphore(SIZE);
    1023 
    1024 }
    1025 
    1026 
    1027 public class PCSem {
    1028 
    1029     public static final void main(final String[] args) {
    1030         Magazzino x = new Magazzino();
    1031         Produttore a1 = new Produttore("Aldo", x);
    1032         Produttore a2 = new Produttore("Alberto", x);
    1033         Consumatore b = new Consumatore("Barbara", x);
    1034         a1.start();
    1035         b.start();
    1036         a2.start();
    1037     }
    1038 
    1039 }
    1040 }}}
    1041 
    1042  * Produttore e consumatore con monitor `PCMon.java`
    1043 
    1044 {{{
    1045 #!java
    1046 import java.util.concurrent.locks.*;
    1047 
    1048 class Actor extends Thread
    1049 {
    1050     public Actor(String nome){
    1051         super(nome);
    1052     }
    1053    
    1054     private Magazzino shared;
    1055     public final Magazzino getShared() {
    1056         return shared;
    1057     }
    1058     public final void setShared(final Magazzino newShared) {
    1059         this.shared = newShared;
    1060     }
    1061 
    1062 }
    1063 
    1064 
    1065 class Produttore extends Actor {
    1066     public Produttore(String nome, Magazzino b) {
    1067         super(nome);
    1068         setShared(b);
    1069     }
    1070    
    1071     public void run(){
    1072         int i = 0;
    1073         while(true){
    1074             System.out.println(getName() + ": Inserisco " + i + " nel buffer");
    1075             getShared().put(i);
    1076             i += 1;
    1077         }
    1078     }
    1079 }
    1080 
    1081 class Consumatore extends Actor{
    1082     public Consumatore(String nome, Magazzino b) {
    1083         super(nome);
    1084         setShared(b);
    1085     }
    1086     public void run(){
    1087         while(true){
    1088             int i = getShared().get();
    1089             System.out.println(getName() + ": Estraggo " + i + " dal buffer");
    1090 
    1091         }
    1092     }
    1093 }
    1094 
    1095 class Magazzino{
    1096     public final static int SIZE = 10;
    1097     private int[] memory = new int[SIZE];
    1098     private int quanti = 0;
    1099    
    1100     public final int get() {
    1101         monitor.lock();
    1102         int ris = -1;
    1103         try{
    1104             String n = Thread.currentThread().getName();
    1105             while (isVuoto()){
    1106                 System.out.println(n + " ha tentato di leggere");
    1107                 empty.await();
    1108             }
    1109             ris = memory[--quanti];
    1110             if (quanti == SIZE - 1) full.signal();
    1111             System.out.println(n + " ha letto");
    1112         } catch (InterruptedException e){
    1113             System.err.println(e);
    1114         } finally {
    1115             monitor.unlock();
    1116             return ris;
    1117         }
    1118     }
    1119 
    1120     public final void put(final int newMemory) {
    1121         monitor.lock();
    1122         try{
    1123             String n = Thread.currentThread().getName();
    1124             while (isPieno()){
    1125                 System.out.println(n + " ha tentato di scrivere");
    1126                 full.await();
    1127             }
    1128             memory[quanti++] = newMemory;
    1129             if (quanti == 1) empty.signal();
    1130             System.out.println(n + " ha scritto");
    1131         } catch (InterruptedException e){
    1132             System.err.println(e);
    1133         } finally {
    1134             monitor.unlock();
    1135         }
    1136     }
    1137 
    1138     public final boolean isVuoto() {
    1139         return quanti == 0;
    1140     }
    1141 
    1142     public final boolean isPieno() {
    1143         return quanti == SIZE;
    1144     }
    1145 
    1146 
    1147     private static final Lock monitor = new ReentrantLock();
    1148     private static final Condition empty = monitor.newCondition();
    1149     private static final Condition full = monitor.newCondition();
    1150 
    1151 
    1152 }
    1153 
    1154 
    1155 public class PCMon {
    1156 
    1157     public static final void main(final String[] args) {
    1158         Magazzino x = new Magazzino();
    1159         Produttore a1 = new Produttore("Aldo", x);
    1160         Produttore a2 = new Produttore("Alberto", x);
    1161         Consumatore b = new Consumatore("Barbara", x);
    1162         a1.start();
    1163         b.start();
    1164         a2.start();
    1165     }
    1166 
    1167 }
    1168 }}}
     191 * Creazione di thread export:trunk/Basic.java
     192   [[IncludeSource(trunk/Basic.java, line_numbers=0)]]
     193
     194 * Memoria condivisa export:trunk/Shared.java
     195   [[IncludeSource(trunk/Shared.java, line_numbers=0)]]
     196
     197 * Memoria condivisa, mutua esclusione ottenuta con `synchronized`, export:trunk/Shared2.java
     198   [[IncludeSource(trunk/Shared2.java, line_numbers=0)]]
     199
     200
     201 * Produttore e consumatore, export:trunk/PC.java
     202   [[IncludeSource(trunk/PC.java, line_numbers=0)]]
     203
     204
     205 * Produttore e consumatore con semafori export:trunk/PCSem.java
     206   [[IncludeSource(trunk/PCSem.java, line_numbers=0)]]
     207
     208 * Produttore e consumatore con monitor export:trunk/PCMon.java
     209   [[IncludeSource(trunk/PCMon.java, line_numbers=0)]]
    1169210
    1170211== Lezione 5 ==
     
    1216257 * '''Turno 2 (24 Aprile 2009)''': [http://homes.dico.unimi.it/sisop/lucidi0809/solab07b.pdf slide] ([http://homes.dico.unimi.it/sisop/lucidi0809/solab07b-handout.pdf Versione stampa])
    1217258
    1218  * mykill.c
    1219 {{{
    1220 #!c#include <sys/types.h>
    1221 #include <signal.h>
    1222 #include <stdlib.h>
    1223 
    1224 int main(int argc, char **argv) {
    1225        
    1226         kill(atoi(argv[1]), 9);
    1227         return 0;
    1228 
    1229 }
    1230 }}}
    1231 
    1232  * mykill-raw1.c
    1233 {{{
    1234 #!c
    1235 #include <stdio.h>
    1236 #include <stdlib.h>
    1237 #include <ansi.h>
    1238 #include <lib.h>
    1239 #include <minix/ipc.h>
    1240 
    1241 int main(int argc, char **argv) {
    1242   message m;
    1243 
    1244   printf("PID: %s SIG: %s\n", argv[1], argv[2]);
    1245  
    1246   m.m1_i1 = atoi(argv[1]);
    1247   m.m1_i2 = atoi(argv[2]);
    1248 
    1249   printf("PID: %d SIG: %d\n", m.m1_i1, m.m1_i2);
    1250  
    1251   return(_syscall(MM, KILL, &m));
    1252 }
    1253 }}}
    1254 
    1255  * mykill-raw2.c
    1256 {{{
    1257 #!c
    1258 #include <stdio.h>
    1259 #include <stdlib.h>
    1260 #include <ansi.h>
    1261 #include <lib.h>
    1262 #include <minix/ipc.h>
    1263 
    1264 int main(int argc, char **argv) {
    1265   message m;
    1266   int status;
    1267 
    1268   printf("PID: %s SIG: %s\n", argv[1], argv[2]);
    1269  
    1270   m.m1_i1 = atoi(argv[1]);
    1271   m.m1_i2 = atoi(argv[2]);
    1272 
    1273   printf("PID: %d SIG: %d\n", m.m1_i1, m.m1_i2);
    1274  
    1275 
    1276   m.m_type = KILL;
    1277   status = _sendrec(MM, &m);
    1278   if (status != 0) {
    1279         /* 'sendrec' itself failed. */
    1280         /* XXX - strerror doesn't know all the codes */
    1281         m.m_type = status;
    1282   }
    1283   if (m.m_type < 0) {
    1284         errno = -m.m_type;
    1285         return(-1);
    1286   }
    1287 
    1288   return(0);
    1289 }
    1290 
    1291 }}}
     259 * export:trunk/mykill.c
     260   [[IncludeSource(trunk/mykill.c, line_numbers=0)]]
     261
     262 * export:trunk/mykill-raw1.c
     263   [[IncludeSource(trunk/mykill-raw1.c, line_numbers=0)]]
     264
     265 * export:trunk/mykill-raw2.c
     266   [[IncludeSource(trunk/mykill-raw2.c, line_numbers=0)]]
     267