Добавил:
hiiamfool
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:2 / T2_Navolockiy_1374
.c/*
Выполнил: Наволоцкий Илья, гр. 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
