Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2 / T2_Navolockiy_1374

.c
Скачиваний:
0
Добавлен:
09.11.2025
Размер:
8.4 Кб
Скачать
/*
 Выполнил: Наволоцкий Илья, гр. 1374
 Задание: Поставщик  потребитель
 Дата выполнения: 26 февраля 2025
*/

/*
 Описание программы:
 Программа реализует модель «Поставщик - потребитель» с использованием POSIX-технологий:

 Вариант 1 (Семафоры):
 - Потоки (pthread_create, pthread_join) для параллельного выполнения задач поставщика и потребителя.
 - POSIX-семафоры (sem_init, sem_wait, sem_post, sem_destroy) для синхронизации доступа к общему буферу.
 - Мьютексы (pthread_mutex_lock, pthread_mutex_unlock) для обеспечения взаимного исключения при работе с критической секцией.
 - Функция clock_gettime для получения точных временных меток входа и выхода из критической секции.

 Вариант 2 (Условные переменные):
 - Потоки (pthread_create, pthread_join) для параллельного выполнения задач поставщика и потребителя.
 - Условные переменные (pthread_cond_wait, pthread_cond_signal, pthread_cond_init, pthread_cond_destroy) для управления ожиданием потоков.
 - Мьютексы (pthread_mutex_lock, pthread_mutex_unlock) для обеспечения взаимного исключения при работе с критической секцией.
 - Функция clock_gettime для получения точных временных меток входа и выхода из критической секции.

 Программа демонстрирует блокировку потоков при переполнении или опустошении буфера.
*/


/*                  
 Скрипт для компиляции и запуска программы:
 Сборка: gcc T2_Navolockiy_1374.c -o T2_Navolockiy_1374 -lpthread
 Запуск: ./T2_Navolockiy_1374
*/


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

#define BUFFER_MAX 5 // Максимальный размер буфера

int Buffer = 0;
pthread_mutex_t mutex;
sem_t full, empty;
pthread_cond_t cond_full, cond_empty;

void log_time(const char* action, const char* mode) {
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    printf("[%ld.%09ld] %s (%s)\n", ts.tv_sec, ts.tv_nsec, action, mode);
}

void* Consumer_Semaphore(void* args) {
    while (1) {
        sem_wait(&full);
        pthread_mutex_lock(&mutex);

        Buffer--;
        log_time("Consumer consumed 1 item", "Semaphore");
        printf("Buffer: %d\n", Buffer);

        pthread_mutex_unlock(&mutex);
        sem_post(&empty);
        sleep(1);
    }
    return NULL;
}

void* Supplier_Semaphore(void* args) {
    while (1) {
        sem_wait(&empty);
        pthread_mutex_lock(&mutex);

        Buffer++;
        log_time("Supplier produced 1 item", "Semaphore");
        printf("Buffer: %d\n", Buffer);

        pthread_mutex_unlock(&mutex);
        sem_post(&full);
        sleep(1);
    }
    return NULL;
}

void* Consumer_Condition(void* args) {
    while (1) {
        pthread_mutex_lock(&mutex);
        while (Buffer == 0) {
            pthread_cond_wait(&cond_full, &mutex);
        }

        Buffer--;
        log_time("Consumer consumed 1 item", "Condition Variable");
        printf("Buffer: %d\n", Buffer);

        pthread_cond_signal(&cond_empty);
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
    return NULL;
}

void* Supplier_Condition(void* args) {
    while (1) {
        pthread_mutex_lock(&mutex);
        while (Buffer == BUFFER_MAX) {
            pthread_cond_wait(&cond_empty, &mutex);
        }

        Buffer++;
        log_time("Supplier produced 1 item", "Condition Variable");
        printf("Buffer: %d\n", Buffer);

        pthread_cond_signal(&cond_full);
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
    return NULL;
}

int main() {
    char mode;
    printf("Выберите режим работы программы:\n");
    printf("'s' - работа через семафоры\n");
    printf("'c' - работа через условные переменные\n");
    
    while (1) {
        printf("Введите 's' или 'c': ");
        if (scanf(" %c", &mode) != 1 || (mode != 's' && mode != 'c')) {
            while (getchar() != '\n'); // Очистка ввода
            printf("Ошибка ввода! Попробуйте снова.\n");
        } else {
            break;
        }
    }

    pthread_t thread_Cons, thread_Sup;
    pthread_mutex_init(&mutex, NULL);
    
    if (mode == 's') {
        sem_init(&full, 0, 0);
        sem_init(&empty, 0, BUFFER_MAX);
        pthread_create(&thread_Cons, NULL, Consumer_Semaphore, NULL);
        pthread_create(&thread_Sup, NULL, Supplier_Semaphore, NULL);
    } else {
        pthread_cond_init(&cond_full, NULL);
        pthread_cond_init(&cond_empty, NULL);
        pthread_create(&thread_Cons, NULL, Consumer_Condition, NULL);
        pthread_create(&thread_Sup, NULL, Supplier_Condition, NULL);
    }

    pthread_join(thread_Cons, NULL);
    pthread_join(thread_Sup, NULL);

    pthread_mutex_destroy(&mutex);
    if (mode == 's') {
        sem_destroy(&full);
        sem_destroy(&empty);
    } else {
        pthread_cond_destroy(&cond_full);
        pthread_cond_destroy(&cond_empty);
    }
    
    return 0;
}


/*
    Лог программы:
        Программа будет выводить текущее значение Buffer после каждого изменения, показывая, как потоки Поставщика и Потребителя взаимодействуют с буфером:

1) Вариант 1

> ./T2_Navolockiy_1374
Выберите режим работы программы:
's' - работа через семафоры
'c' - работа через условные переменные
Введите 's' или 'c': s
[1740597189.571888052] Supplier produced 1 item (Semaphore)
Buffer: 1
[1740597189.571921856] Consumer consumed 1 item (Semaphore)
Buffer: 0
[1740597190.572006484] Supplier produced 1 item (Semaphore)
Buffer: 1
[1740597190.572048878] Consumer consumed 1 item (Semaphore)
Buffer: 0
[1740597191.572265788] Supplier produced 1 item (Semaphore)
Buffer: 1
[1740597191.572301617] Consumer consumed 1 item (Semaphore)
Buffer: 0
[1740597192.572627481] Supplier produced 1 item (Semaphore)
Buffer: 1
[1740597192.572683285] Consumer consumed 1 item (Semaphore)
Buffer: 0
[1740597193.572798854] Supplier produced 1 item (Semaphore)
Buffer: 1
[1740597193.572850188] Consumer consumed 1 item (Semaphore)
Buffer: 0
[1740597194.573194071] Supplier produced 1 item (Semaphore)
Buffer: 1
[1740597194.573265101] Consumer consumed 1 item (Semaphore)
Buffer: 0
^C


2) Вариант 2

> ./T2_Navolockiy_1374
Выберите режим работы программы:
's' - работа через семафоры
'c' - работа через условные переменные
Введите 's' или 'c': c
[1740597226.935043074] Supplier produced 1 item (Condition Variable)
Buffer: 1
[1740597226.935080370] Consumer consumed 1 item (Condition Variable)
Buffer: 0
[1740597227.935171353] Supplier produced 1 item (Condition Variable)
Buffer: 1
[1740597227.935212211] Consumer consumed 1 item (Condition Variable)
Buffer: 0
[1740597228.935546875] Supplier produced 1 item (Condition Variable)
Buffer: 1
[1740597228.935636483] Consumer consumed 1 item (Condition Variable)
Buffer: 0
[1740597229.935767417] Supplier produced 1 item (Condition Variable)
Buffer: 1
[1740597229.935945585] Consumer consumed 1 item (Condition Variable)
Buffer: 0
[1740597230.936166895] Supplier produced 1 item (Condition Variable)
Buffer: 1
[1740597230.936223258] Consumer consumed 1 item (Condition Variable)
Buffer: 0
[1740597231.936596964] Supplier produced 1 item (Condition Variable)
Buffer: 1
[1740597231.936676515] Consumer consumed 1 item (Condition Variable)
Buffer: 0
^C

*/
Соседние файлы в папке 2