/******************************************************************************/ /** @file "Pthreads/C/Ispitni zadaci/si4mps_k1_20102011_z5.c" @brief Simulacija benzinske stanice @author Marko Mišić */ /******************************************************************************/ #include #include #include #include #include #define VREME_POTROSACI_DONJE 120 #define VREME_POTROSACI_GORNJE 600 #define VREME_TOCENJA_DONJE 30 #define VREME_TOCENJA_GORNJE 90 #define KOLICINA_GORIVA_DONJA 5 #define KOLICINA_GORIVA_GORNJA 40 typedef struct { unsigned utroseno_gorivo; unsigned vreme_cekanja; unsigned vreme_tocenja; } Aparat; typedef struct { unsigned tid; unsigned* rezervoar; unsigned* kraj; Aparat* aparati; unsigned broj_niti; unsigned* broj_kreiranih; pthread_mutex_t* rezervoar_mutex; pthread_mutex_t* pocetak_mutex; pthread_cond_t* pocetak_cond; } Nit; unsigned long iurng(unsigned long* seed) { return *seed = 429493445 * (*seed) + 907633385; } double randomd(unsigned long* seed) { return( iurng(seed) / 4294967296.); } unsigned gen_opseg (int donja, int gornja, unsigned long* seed) { double gen = randomd(seed); unsigned ret = (unsigned)( gen * (gornja - donja) + donja); return ret; } void* aparat_thread (void* d) { Nit* nit = (Nit*)d; unsigned long seed = (unsigned long)time(NULL)%(nit->tid+13) + 23*1000*nit->tid; printf("Seed: %u\n", seed); pthread_mutex_lock(nit->pocetak_mutex); if (*(nit->broj_kreiranih) < nit->broj_niti) { pthread_cond_wait(nit->pocetak_cond, nit->pocetak_mutex); } pthread_mutex_unlock(nit->pocetak_mutex); //srand(time(NULL)%(nit->tid+1)); putchar('a'); nit->aparati[nit->tid].utroseno_gorivo = 0; nit->aparati[nit->tid].vreme_cekanja = 0; nit->aparati[nit->tid].vreme_tocenja = 0; while (!*(nit->kraj)) { unsigned vreme_potrosac;// = gen_opseg(VREME_POTROSACI_DONJE, VREME_POTROSACI_GORNJE); unsigned vreme_tocenja;// = gen_opseg(VREME_TOCENJA_DONJE, VREME_TOCENJA_GORNJE); unsigned kolicina;// = gen_opseg(KOLICINA_GORIVA_DONJA, KOLICINA_GORIVA_GORNJA); //pthread_mutex_lock(nit->rezervoar_mutex); vreme_potrosac = gen_opseg(VREME_POTROSACI_DONJE, VREME_POTROSACI_GORNJE, &seed); vreme_tocenja = gen_opseg(VREME_TOCENJA_DONJE, VREME_TOCENJA_GORNJE, &seed); kolicina = gen_opseg(KOLICINA_GORIVA_DONJA, KOLICINA_GORIVA_GORNJA, &seed); //pthread_mutex_unlock(nit->rezervoar_mutex); printf("%u\n",vreme_potrosac); Sleep(vreme_potrosac); nit->aparati[nit->tid].vreme_cekanja += vreme_potrosac; pthread_mutex_lock(nit->rezervoar_mutex); if (kolicina > *(nit->rezervoar)) { pthread_mutex_unlock(nit->rezervoar_mutex); break; } *(nit->rezervoar) -= kolicina; pthread_mutex_unlock(nit->rezervoar_mutex); nit->aparati[nit->tid].utroseno_gorivo += kolicina; Sleep(vreme_tocenja); nit->aparati[nit->tid].vreme_tocenja += vreme_tocenja; } putchar('b'); free(nit); pthread_exit(NULL); return NULL; } void benzinska_stanica () { unsigned rezervoar; unsigned long seed; unsigned broj_niti, i; unsigned kraj = 0; pthread_attr_t attributes; pthread_t* niti; pthread_mutex_t rezervoar_mutex; pthread_mutex_t pocetak_mutex; pthread_cond_t pocetak_cond; Nit* nit; Aparat* aparati; // Inicijalizacija pthread_attr_init(&attributes); pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE); pthread_mutex_init(&rezervoar_mutex, NULL); pthread_mutex_init(&pocetak_mutex, NULL); pthread_cond_init (&pocetak_cond, NULL); printf("Koliko aparata zelite da aktivirate?"); scanf("%u", &broj_niti); seed = time(NULL)%11; rezervoar = gen_opseg(1000,2000, &seed); niti = malloc (broj_niti * sizeof(pthread_t)); aparati = malloc (broj_niti * sizeof(Aparat)); if (aparati == NULL) { printf("Neuspela alokacija memorije!"); exit(1); } printf("\nStanje rezervoara pre tocenja: %u\n", rezervoar); for(i = 0; i < broj_niti; i++) { // Napravi POSIX nit. //printf("Stvaram POSIX nit %d\n", i); int rc; nit = malloc(sizeof(Nit)); if (nit == NULL) { printf("Neuspela alokacija memorije!"); exit(1); } nit->tid = i; nit->broj_niti = broj_niti; nit->broj_kreiranih = &i; nit->kraj = &kraj; nit->rezervoar = &rezervoar; nit->aparati = aparati; nit->rezervoar_mutex = &rezervoar_mutex; nit->pocetak_mutex = &pocetak_mutex; nit->pocetak_cond = &pocetak_cond; rc = pthread_create(&niti[i], NULL, aparat_thread, (void *)nit); if (rc) { printf("GREŠKA: povratna vrednost iz pthread_create(): %d\n", rc); exit(2); } } pthread_cond_broadcast(&pocetak_cond); Sleep(15000); kraj = 1; // Sacekaj da svi zavrse i ispisi rezultate for (i=0; i < broj_niti; i++) { pthread_join(niti[i], NULL); printf("Aparat %u podaci:\n", i); printf("\t utroseno gorivo %u \n", aparati[i].utroseno_gorivo); printf("\t vreme cekanja %u \n", aparati[i].vreme_cekanja); printf("\t vreme tocenja %u \n", aparati[i].vreme_tocenja); } printf("\nStanje rezervoara nakon tocenja: %u", rezervoar); free(aparati); free(niti); pthread_mutex_destroy(&rezervoar_mutex); pthread_mutex_destroy(&pocetak_mutex); pthread_cond_destroy(&pocetak_cond); pthread_attr_destroy(&attributes); } int main(int argc, char *argv[]) { //srand(time(NULL)); benzinska_stanica(); return 0; }