Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <stdint.h>
- #include <semaphore.h>
- #include <math.h>
- #define PHILOSOPHERS_COUNT 5
- #define THINKING 1
- #define HUNGRY 2
- #define EATING 3
- #define EATINGS_LIMIT 2 // лимит обедов
- #define MAX_THINKING_TIME 5 // максимальное время на размышления в сек
- #define MAX_EATING_TIME 5 // максимальное время на обед в сек
- typedef struct {
- uint8_t num; // номер философа
- sem_t* forks; // семафоры-вилки
- int* state; // массив состояний философов
- } PhilThreadParams;
- pthread_mutex_t printf_mutex; // мьютекс для printf
- pthread_mutex_t states_mutex; // мьютекс для массива состояний
- void print_forks_stats(PhilThreadParams* params)
- {
- int i;
- pthread_mutex_lock(&printf_mutex);
- printf("FORKS {");
- for (i = 0 ; i < PHILOSOPHERS_COUNT ; i++) {
- printf("%d:", i);
- int sval = 0;
- sem_getvalue(¶ms->forks[i], &sval);
- if(sval == 0) {
- printf("in use");
- } else {
- printf("free");
- }
- if (i != PHILOSOPHERS_COUNT - 1) {
- printf(", ");
- }
- }
- printf("}\n");
- pthread_mutex_unlock(&printf_mutex);
- }
- void print_philosophers_stats(PhilThreadParams* params)
- {
- int i;
- pthread_mutex_lock(&printf_mutex);
- printf("PHILOSOPHERS {");
- for (i = 0 ; i < PHILOSOPHERS_COUNT ; i++) {
- printf("%d:", i);
- pthread_mutex_lock(&states_mutex);
- switch (params->state[i])
- {
- case THINKING:
- printf("THINKING");
- break;
- case HUNGRY:
- printf("HUNGRY");
- break;
- case EATING:
- printf("EATING");
- break;
- }
- pthread_mutex_unlock(&states_mutex);
- if (i != PHILOSOPHERS_COUNT - 1) {
- printf(", ");
- }
- }
- printf("}\n");
- pthread_mutex_unlock(&printf_mutex);
- }
- // функуия размышлений
- void think(PhilThreadParams* params)
- {
- int thinking_time = rand() % MAX_THINKING_TIME; // генерируем время размышлений
- pthread_mutex_lock(&printf_mutex);
- printf("Philosopher %d thinking for %d seconds\n", params->num, thinking_time);
- pthread_mutex_unlock(&printf_mutex);
- sleep(thinking_time); // думаем
- pthread_mutex_lock(&states_mutex);
- params->state[params->num] = HUNGRY; // философ проголодался
- pthread_mutex_unlock(&states_mutex);
- }
- // функция официанта
- void waiter(PhilThreadParams* params) {
- int left = params->num;
- int right = (params->num + 1) % PHILOSOPHERS_COUNT;
- sem_wait(¶ms->forks[left]);
- printf("Philosopher %d take fork #%d\n", params->num, left);
- // берем вторую вилку
- sem_wait(¶ms->forks[right]);
- printf("Philosopher %d take fork #%d\n", params->num, right);
- pthread_mutex_lock(&states_mutex);
- params->state[params->num] = EATING; // взяли вилки
- pthread_mutex_unlock(&states_mutex);
- }
- // функция обеда
- void eating(PhilThreadParams* params)
- {
- int eating_time = rand() % MAX_EATING_TIME; // генерируем время обеда
- pthread_mutex_lock(&printf_mutex);
- printf("Philosopher %d eating for %d seconds\n", params->num, eating_time);
- pthread_mutex_unlock(&printf_mutex);
- sleep(eating_time); // обедаем
- }
- // кладем вилки
- void put_forks(PhilThreadParams* params) {
- int left = params->num;
- int right = (params->num + 1) % PHILOSOPHERS_COUNT;
- sem_post(¶ms->forks[left]);
- printf("Philosopher %d put fork #%d\n", params->num, left);
- sem_post(¶ms->forks[right]);
- printf("Philosopher %d put fork #%d\n", params->num, right);
- pthread_mutex_lock(&states_mutex);
- params->state[params->num] = THINKING; // философ наелся, можно думать
- pthread_mutex_unlock(&states_mutex);
- }
- // функция потока философа
- void philosopher_thread(PhilThreadParams* params)
- {
- int eatings_count = 0;
- pthread_mutex_lock(&printf_mutex);
- printf("PHILOSHPER %d HELLO\n", params->num);
- pthread_mutex_unlock(&printf_mutex);
- while (1) {
- print_philosophers_stats(params);
- think(params);
- waiter(params);
- eating(params);
- put_forks(params);
- eatings_count++;
- if (eatings_count == EATINGS_LIMIT) {
- break;
- }
- }
- pthread_mutex_lock(&printf_mutex);
- printf("PHILOSHPER %d BYE\n", params->num);
- pthread_mutex_unlock(&printf_mutex);
- pthread_exit(NULL);
- }
- int main(int argc, char *argv[]) {
- sem_t forks[PHILOSOPHERS_COUNT];
- int phil_states[PHILOSOPHERS_COUNT];
- PhilThreadParams params[PHILOSOPHERS_COUNT];
- int i;
- // инициализируем мьютексы
- pthread_mutex_init(&printf_mutex, NULL);
- pthread_mutex_init(&states_mutex, NULL);
- pthread_mutex_lock(&printf_mutex);
- printf("Main thread start\n");
- pthread_mutex_unlock(&printf_mutex);
- for (i = 0 ; i < PHILOSOPHERS_COUNT ; i++) {
- sem_init(&forks[i], 0, 1); // инициализация семафора
- phil_states[i] = THINKING;
- }
- pthread_t philosophers_threads[PHILOSOPHERS_COUNT];
- for (i = 0 ; i < PHILOSOPHERS_COUNT ; i++) {
- params[i].num = i;
- params[i].forks = forks;
- params[i].state = phil_states;
- pthread_create(&philosophers_threads[i], NULL, philosopher_thread, ¶ms[i]);
- }
- for (i = 0 ; i < PHILOSOPHERS_COUNT ; i++) {
- pthread_join(philosophers_threads[i], NULL);
- }
- for (i = 0 ; i < PHILOSOPHERS_COUNT ; i++) {
- sem_destroy(&forks[i]); // уничтожение семафора
- }
- pthread_mutex_lock(&printf_mutex);
- printf("Main thread end\n");
- pthread_mutex_unlock(&printf_mutex);
- // уничтожаем мьютексы
- pthread_mutex_destroy(printf_mutex);
- pthread_mutex_destroy(states_mutex);
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement