| 646 | |
| 647 | * Thread '''con''' memoria condivisa, mutua esclusione ottenuta con semaforo `threads-sem.c` |
| 648 | |
| 649 | {{{ |
| 650 | #!c |
| 651 | #include <unistd.h> |
| 652 | #include <stdio.h> |
| 653 | #include <stdlib.h> |
| 654 | #include <signal.h> |
| 655 | #include <sched.h> |
| 656 | #include <semaphore.h> |
| 657 | |
| 658 | sem_t S; |
| 659 | |
| 660 | void enter_section(){ |
| 661 | if (sem_wait(&S) < 0){ |
| 662 | perror("Errore semaforo (down)"); |
| 663 | exit(1); |
| 664 | } |
| 665 | } |
| 666 | |
| 667 | |
| 668 | |
| 669 | void leave_section() |
| 670 | { |
| 671 | if (sem_post(&S) < 0){ |
| 672 | perror("Errore semaforo (up)"); |
| 673 | exit(1); |
| 674 | } |
| 675 | } |
| 676 | |
| 677 | int run(const int p, void* s) |
| 678 | { |
| 679 | int* shared = (int*) s; |
| 680 | while (enter_section(), |
| 681 | *shared < 10) { |
| 682 | printf("Processo figlio (%d). s = %d\n", |
| 683 | getpid(), *shared); |
| 684 | sleep(1); |
| 685 | if (!(*shared < 10)){ |
| 686 | printf("Corsa critica!!!!\n"); |
| 687 | abort(); |
| 688 | } |
| 689 | *shared += 1; |
| 690 | leave_section(); |
| 691 | sched_yield(); |
| 692 | } |
| 693 | return 0; |
| 694 | } |
| 695 | |
| 696 | int main(void){ |
| 697 | |
| 698 | int shared = 0; |
| 699 | |
| 700 | if (sem_init(&S, |
| 701 | 0 /* thread local semaphore */, |
| 702 | 1 /* init value */ |
| 703 | ) < 0){ |
| 704 | perror("Errore semaforo"); |
| 705 | exit(1); |
| 706 | } |
| 707 | |
| 708 | /* int clone(int (*fn)(void *), |
| 709 | * void *child_stack, |
| 710 | * int flags, |
| 711 | * void *arg); |
| 712 | * crea una copia del chiamante (con le caratteristiche |
| 713 | * specificate da flags) e lo esegue partendo da fn */ |
| 714 | if (clone(run, /* il nuovo |
| 715 | * processo esegue run(shared), vedi quarto |
| 716 | * parametro */ |
| 717 | malloc(4096)+4096, /* lo stack del nuovo processo |
| 718 | * (cresce verso il basso!) */ |
| 719 | CLONE_VM | SIGCHLD, /* la (virtual) memory e` condivisa */ |
| 720 | &shared) < 0){ |
| 721 | perror("Errore nella creazione"); |
| 722 | exit(1); |
| 723 | } |
| 724 | |
| 725 | if (clone(run, malloc(4096)+4096, CLONE_VM | SIGCHLD, &shared) < 0){ |
| 726 | perror("Errore nella creazione"); |
| 727 | exit(1); |
| 728 | } |
| 729 | |
| 730 | while(shared < 10) { |
| 731 | sleep(1); |
| 732 | printf("Processo padre. s = %d\n", shared); |
| 733 | } |
| 734 | |
| 735 | sem_destroy(&S); |
| 736 | return 0; |
| 737 | } |
| 738 | }}} |
| 739 | |
| 740 | {{{ |
| 741 | #!sh |
| 742 | cc -o threads-sem threads-sem.c -lrt |
| 743 | }}} |
| 744 | |