ПОС/Надокнада 2016

Извор: SI Wiki
Пређи на навигацију Пређи на претрагу

Одрицање одговорности: уз скоро све задатке из нити прошлих година дати су почетни .cpp и .h фајлови (који притом често нису доступни у штурим материјалима). С обзиром да су 2020/21 школске године на вежбама из POS-а приказани само задаци у C-у, ништа налик прошлим годинама, решења ће бити дата у духу тих C задатака из школске године 2020/21.

Задатак 1

Поставка

(7п) Написати програм у коме главна нит (креирана над функцијом main) треба да покрене три инстанце нити које исписују поруку "I am <ThreadX>!" (<ThreadX> је име те нити). Када све три нити испишу своју поруку, у било ком редоследу, тада главна нит исписује поруку "END" и заврсава[sic] програм.

Решење

#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);
}

Задатак 2

Поставка

(8п) Две нити, једна класе NitX, а друга класе NitY, наизменично треба да инкрементирају вредност променљиве counter. NitX прва почиње са увећавањем. Обезедити такву синхронизацију.

Решење

#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;
}