source: trunk/threads-sem.c @ 2

Last change on this file since 2 was 2, checked in by monga, 9 years ago

Importazione sorgenti

File size: 2.9 KB
Line 
1/* Copyright (C) 2009 by Mattia Monga <mattia.monga@unimi.it> */
2/* $Id$ */
3
4#include <unistd.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <signal.h>
8#include <sched.h>
9#include <semaphore.h>
10
11void enter_section(sem_t *s){ 
12        if (sem_wait(s) < 0){
13                perror("Errore semaforo (down)");
14                exit(1);
15        }
16}
17
18       
19
20void leave_section(sem_t *s)
21{
22        if (sem_post(s) < 0){
23                perror("Errore semaforo (up)");
24                exit(1);
25        }
26}
27
28int run(const int p, void* s)
29{
30        int* shared = (int*)s; /* alias per comodita` */
31        while (enter_section((sem_t*)shared[1]), 
32               shared[0] < 10) {
33                sleep(1);
34                printf("Processo figlio (%d). s = %d\n", 
35                       getpid(), shared[0]);
36                if (!(shared[0] < 10)){
37                        printf("Corsa critica!!!!\n");
38                        abort();
39                }
40                shared[0] += 1;
41                leave_section((sem_t*)shared[1]);
42                sched_yield();
43        }
44        return 0;
45}
46
47int run0(void*s){ return run(0, s); }
48int run1(void*s){ return run(1, s); }
49       
50
51int main(void){
52 
53        int shared[4] = {0 , 0, 0, 0};
54
55        sem_t *ss;
56        if (sem_init(ss, 
57                     0 /* thread local semaphore */,
58                     0 /* init value */
59                    ) < 0){
60                perror("Errore semaforo");
61                exit(1);
62        }
63        shared[1] = (int)ss;
64
65        /* int clone(int (*fn)(void *),
66         *           void *child_stack,
67         *           int flags,
68         *           void *arg);
69         * crea una copia del chiamante (con le caratteristiche
70         * specificate da flags) e lo esegue partendo da fn */
71        if (clone(run0, /* il nuovo
72                         * processo esegue run(shared), vedi quarto
73                         * parametro */
74                  malloc(4096)+4096,  /* lo stack del nuovo processo
75                                       *  (cresce verso il basso!) */
76                  CLONE_VM | SIGCHLD, /* la (virtual) memory e` condivisa */
77                  shared) < 0){
78                perror("Errore nella creazione");
79                exit(1);
80        } 
81
82        if (clone(run1, malloc(4096)+4096,  CLONE_VM | SIGCHLD, shared) < 0){
83                perror("Errore nella creazione");
84                exit(1);
85        } 
86
87        /* Memoria condivisa: i due figli nell'insieme eseguono 10 o
88         * 11 volte: e` possibile una corsa critica. Il padre
89         * condivide shared[0] con i figli */
90
91        while(shared[0] < 10) {
92                sleep(1);
93                printf("Processo padre. s = %d %d %d %d\n", 
94                       shared[0],
95                       shared[1],
96                       shared[2],
97                       shared[3]);
98        }
99        sem_destroy(ss);
100        return 0;
101}
102
103   
104       
105 
106
107
108
109/* Local Variables: */
110/* compile-command: "make -k " */
111/* End: */
Note: See TracBrowser for help on using the repository browser.