| | 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 | |