Задача о супермаркете с использованием семафора на C
Всем привет! Такая задача "Ввести мьютексы, семафоры или блокировки чтения-записи для защиты критических секций. Если в задании указан конкретный механизм для защиты, использовать только его. Задача о супермаркете. В супермаркете работают два кассира, покупатели заходят в супермаркет, делают покупки и становятся в очередь к случайному кассиру. Пока очередь пуста, кассир спит, как только появляется покупатель, кассир просыпается. Покупатель спит в очереди, пока не подойдет к кассиру. Создать многопоточное приложение, моделирующее рабочий день супермаркета."
Вот что я накалякал (не кидайте тапками за говнокод, я не знаком с Си вообще, это ужас, что нам эту методичку дали). В программе работает только функция покупателя, а кассиры бесконечно каждую секунду обслуживают покупателя 0. Я не понимаю почему, как будто семафоры не работают, но вроде все делаю правильно (по крайней мере как я понял работу семафоров)
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define NUM_CUSTOMERS 10
#define NUM_CASHIERS 2
typedef struct {
int customers[NUM_CUSTOMERS];
int front;
int rear;
} Queue;
Queue queue[NUM_CASHIERS];
pthread_mutex_t mutex_cashiers[NUM_CASHIERS]; // Мьютексы для кассиров
sem_t sem_cashiers[NUM_CASHIERS];
void initializeQueue(Queue *queue) {
queue->front = 0;
queue->rear = 0;
}
void enqueue(Queue *queue, int item) {
queue->customers[queue->rear] = item;
queue->rear = (queue->rear + 1) % NUM_CUSTOMERS;
}
int dequeue(Queue *queue) {
int item = queue->customers[queue->front];
queue->front = (queue->front + 1) % NUM_CUSTOMERS;
return item;
}
void *cashier(void *args) {
int cashier_number = *((int *)args);
while (1) {
sem_wait(&sem_cashiers[cashier_number]);
pthread_mutex_lock(&mutex_cashiers[cashier_number]);
int customer_num = dequeue(&queue[cashier_number]);
printf("Касса %d обслуживает покупателя %d.\n", cashier_number + 1, customer_num);
sleep(1);
printf("Касса %d завершила обслуживание покупателя %d.\n", cashier_number + 1, customer_num);
pthread_mutex_unlock(&mutex_cashiers[cashier_number]);
}
}
void *customer(void *args) {
int customer_number = *((int *)args);
sleep(rand() % 10 + 1);
printf("Покупатель %d зашёл в магазин и делает покупки...\n", customer_number);
sleep(rand() % 10 + 1);
int cashier_choice = rand() % NUM_CASHIERS;
pthread_mutex_lock(&mutex_cashiers[cashier_choice]);
enqueue(&queue[cashier_choice], customer_number);
printf("Покупатель %d встал в очередь к Кассе %d.\n", customer_number, cashier_choice + 1);
sem_post(&sem_cashiers[cashier_choice]);
pthread_mutex_unlock(&mutex_cashiers[cashier_choice]);
return NULL;
}
int main(void) {
pthread_t threads_cashiers[NUM_CASHIERS];
pthread_t threads_customers[NUM_CUSTOMERS];
for (int i = 0; i < NUM_CASHIERS; i++) {
int *cashier_number = malloc(sizeof(int));
*cashier_number = i;
pthread_create(&threads_cashiers[i], NULL, cashier, (void *)cashier_number);
initializeQueue(&queue[i]);
pthread_mutex_init(&mutex_cashiers[i], NULL);
sem_init(&sem_cashiers[i], 0, 0);
}
for (int i = 0; i < NUM_CUSTOMERS; i++) {
int *customer_number = malloc(sizeof(int));
*customer_number = i;
pthread_create(&threads_customers[i], NULL, customer, (void *)customer_number);
}
for (int i = 0; i < NUM_CUSTOMERS; i++) {
pthread_join(threads_customers[i], NULL);
}
for (int i = 0; i < NUM_CASHIERS; i++) {
pthread_mutex_destroy(&mutex_cashiers[i]);
sem_destroy(&sem_cashiers[i]);
pthread_join(threads_cashiers[i], NULL);
}
return 0;
}
Ответы (1 шт):
В общем, проблема в том, что я сижу на MacOS. По своей тупости не обращал внимания на предупреждение sem_t is derpicated. Сегодня со свежей головой начал опять думать над заданием и сразу обратил внимание на предупреждение, загуглил. Вот ответ: https://stackoverflow.com/questions/27736618/why-are-sem-init-sem-getvalue-sem-destroy-deprecated-on-mac-os-x-and-w