POS/Nadoknada 2016

Izvor: SI Wiki
Pređi na navigaciju Pređi na pretragu

Odricanje odgovornosti: uz skoro sve zadatke iz niti prošlih godina dati su početni .cpp i .h fajlovi (koji pritom često nisu dostupni u šturim materijalima). S obzirom da su 2020/21 školske godine na vežbama iz POS-a prikazani samo zadaci u C-u, ništa nalik prošlim godinama, rešenja će biti data u duhu tih C zadataka iz školske godine 2020/21.

Zadatak 1

Postavka

(7p) Napisati program u kome glavna nit (kreirana nad funkcijom main) treba da pokrene tri instance niti koje ispisuju poruku "I am <ThreadX>!" (<ThreadX> je ime te niti). Kada sve tri niti ispišu svoju poruku, u bilo kom redosledu, tada glavna nit ispisuje poruku "END" i zavrsava[sic] program.

Rešenje

#include <semaphore.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#define THREAD_CNT 3

typedef struct shared_data {
    sem_t ready;
} shared_data;

typedef struct thread_data {
    shared_data *data;
    int thread_id;
} thread_data;

void *sub_thread(void *param) {
    thread_data *t_data = (thread_data*)param;
    shared_data *s_data = t_data->data;

    printf("I am thread %d\n", t_data->thread_id);
    sem_post(&s_data->ready);
    
    return NULL;
}

void *main_thread(void *param) {
    shared_data *s_data = (shared_data*)param;
    thread_data t_data[THREAD_CNT];

    pthread_t threads[THREAD_CNT];
    for (int i = 0; i < THREAD_CNT; i++) {
        t_data[i].data = s_data;
        t_data[i].thread_id = i;
        pthread_create(&threads[i], 0, sub_thread, &t_data[i]);
    }
    for (int i = 0; i < THREAD_CNT; i++) 
        pthread_join(threads[i], 0);

    sem_wait(&s_data->ready);
    sem_wait(&s_data->ready);
    sem_wait(&s_data->ready);

    printf("END\n");
    return NULL;
}

int main() {
    shared_data data;

    sem_init(&data.ready, 0, 0);
    pthread_t main;
    pthread_create(&main, 0, main_thread, &data);
    pthread_join(main, 0);

    sem_destroy(&data.ready);
}

Zadatak 2

Postavka

(8p) Dve niti, jedna klase NitX, a druga klase NitY, naizmenično treba da inkrementiraju vrednost promenljive counter. NitX prva počinje sa uvećavanjem. Obezediti takvu sinhronizaciju.

Rešenje

#include <semaphore.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>

typedef struct shared_data {
    int *counter;
    int limit;
    sem_t mutex_x;
    sem_t mutex_y;
} shared_data;

void *NitX(void *param) {
    shared_data *data = (shared_data*)param;
    int i = data->limit;

    while (i-- > 0) {
        sem_wait(&data->mutex_x);
        (*(data->counter))++;
        sem_post(&data->mutex_y);
    }

    return NULL;
}
void *NitY(void *param) {
    shared_data *data = (shared_data*)param;
    int i = data->limit;

    while (i-- > 0) {
        sem_wait(&data->mutex_y);
        (*(data->counter))++;
        sem_post(&data->mutex_x);
    }

    return NULL;
}

int main(int argc, char *argv[]) {
    srand(time(0));
    shared_data data;

    data.limit = 5;
    data.counter = (int*)malloc(sizeof(int));
    *data.counter = 0;
    
    sem_init(&data.mutex_x, 0, 1);
    sem_init(&data.mutex_y, 0, 0);

    pthread_t x, y;
    pthread_create(&x, 0, NitX, &data);
    pthread_create(&y, 0, NitY, &data);

    pthread_join(x, 0);
    pthread_join(y, 0);

    sem_destroy(&data.mutex_x);
    sem_destroy(&data.mutex_y);
    free(data.counter);

    printf("counter je sada %d\n", *data.counter);

    return 0;
}