Skip to content
Snippets Groups Projects
race_fixed_sem_mutex.c 1.81 KiB
/** Pikku esimerkki yhdenaikaisuuden aiheuttamasta kilpa-ajosta eli
 *  race conditionista. Summaus globaaliin muuttujaan vaatii useita
 *  konekielisiä käskyjä, joiden välissä voi tulla kellokeskeytys!
 *
 *  Ongelma on tässä hallittu keskinäisesti poissulkevalla (mutual
 *  exclusion, mutex) lukolla, joka on toteutettu semaforilla. Tämä on
 *  "ensimmäinen esimerkki" semaforin käytöstä ja siitä kuinka MutEx
 *  voidaan sellaisella toteuttaa. Semafori on kuitenkin
 *  yleiskäyttöisempi, ja tässä tapauksessa tarpeettoman "vahva"
 *  menetelmä, koska pthreads-kirjastossa on myös yksinkertaisempi
 *  poissulkuratkaisu: race_fixed_mutex.c
 *
 *  HUOM: Esimerkkien lyhentämiseksi näissä ei tarkisteta,
 *  onnistuivatko operaatiot. Oikeassa ohjelmassa AINA tarkistettava
 *  esim. onnistuiko säikeen luonti vai ei, ja käsiteltävä
 *  epäonnistuminen!!
 */

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <pthread.h>
#include <semaphore.h>

#define N 100000000
uint64_t summa = 0;

sem_t mymutex;

/** 
 * Nyt on synkronoitu semaforilla (vertaa pthread -kirjaston mutexiin).
 * Hiukan monimutkaisempi; tähän tarkoitukseen pthreadin mutex parempi.
 */
void * saikeen_koodi(void *v) {
    int i;
    for (i = 1; i <= N; i++) {
        sem_wait(&mymutex); // Dijkstran "P()-operaatio"
        summa++;
        sem_post(&mymutex); // Dijkstran "V()-operaatio"
    }
    return NULL;
}

int main(int argc, char *argv[]) {
    pthread_t saieA, saieB;

    sem_init(&mymutex, 0, 1);

    pthread_create(&saieA, NULL, saikeen_koodi, NULL);
    pthread_create(&saieB, NULL, saikeen_koodi, NULL);
     
    pthread_join(saieA, NULL);
    pthread_join(saieB, NULL);
     
    sem_destroy(&mymutex);

    printf("Summa on %" PRId64 " - pittäis olla %" PRId64 "\n", summa, (uint64_t) 2*N);
     
    return 0;
}