-
Jonne Itkonen authored
Välilyönti tai tyhjä rivi oikeassa kohdassa lisää luettavuutta tai on pilkun viilausta.
Jonne Itkonen authoredVälilyönti tai tyhjä rivi oikeassa kohdassa lisää luettavuutta tai on pilkun viilausta.
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;
}