Advertisement
artmexbet

Mutex

May 7th, 2024 (edited)
544
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.33 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <pthread.h>
  5. #include <string.h>
  6.  
  7. #define ROWS 4
  8. #define COLS 5
  9.  
  10. struct ThreadResult {
  11.     int count;
  12.     int indexes[6];
  13. };
  14.  
  15. struct TaskQueue {
  16.     struct TaskQueue *next;
  17.     struct ThreadResult result;
  18.     int threadNumber;
  19. };
  20.  
  21. struct ThreadInfo {
  22.     int matrix[ROWS][COLS];
  23.     int deltaX;
  24.     int deltaY;
  25.     int threadNumber;
  26. };
  27.  
  28. void fill_matrix(int array[ROWS][COLS]) {
  29.     srand(time(NULL));
  30.     for (int i = 0; i < ROWS; i++) {
  31.         for (int j = 0; j < COLS; j++) {
  32.             array[i][j] = 1 + rand() % 3;
  33.         }
  34.     }
  35. }
  36.  
  37. void print_matrix(int array[ROWS][COLS]) {
  38.     for (int i = 0; i < ROWS; i++) {
  39.         for (int j = 0; j < COLS; j++) {
  40.             printf("%d ", array[i][j]);
  41.         }
  42.         printf("\n");
  43.     }
  44. }
  45.  
  46. pthread_mutex_t mutex;
  47. struct TaskQueue *head = NULL;
  48. struct TaskQueue *new = NULL;
  49. struct TaskQueue *tail = NULL;
  50.  
  51. void *get_values(void *info_) {
  52.     struct ThreadInfo *info = (struct ThreadInfo *) info_;
  53.     struct ThreadResult *result = (struct ThreadResult *) malloc(sizeof(struct ThreadResult));
  54.     result->count = 0;
  55.     for (int i = 0; i < ROWS; i++) {
  56.         for (int j = 0; j < COLS; j++) {
  57.             int k = 0;
  58.             int lengthOfHorizontal = 0; // Сюда сохраняем длину повторяющихся символов в строке
  59.             while (0 < j + k && j + k < COLS && info->matrix[i][j + k] == info->matrix[i][j]) {
  60.                 lengthOfHorizontal++;
  61.                 int l = 0;
  62.                 int lengthOfVertical = 0; // Сюда сохраняем длину повторяющихся символов в столбце
  63.                 while (0 < i + l && i + l < ROWS && info->matrix[i + l][j + k] == info->matrix[i][j + k]) {
  64.                     lengthOfVertical++;
  65.                     l += info->deltaX;
  66.                 }
  67.                 if (lengthOfHorizontal + lengthOfVertical > result->count) {
  68.                     result->indexes[0] = i;
  69.                     result->indexes[1] = j;
  70.                     result->indexes[2] = i;
  71.                     result->indexes[3] = j + k;
  72.                     if (l != 0) {
  73.                         result->indexes[4] = i + l - 1 * info->deltaX;
  74.                         // Если в l добавлялись элементы, значение в ней будет на единицу больше (или меньше,
  75.                         // в зависимости от deltaX) из-за того, что мы сначала проверяем, а уже затем увеличиваем l
  76.                         // в цикле while выше
  77.                     } else {
  78.                         // Если же l = 0, вычитать ничего не нужно, нужно лишь записать эту же строку в нужный индекс
  79.                         result->indexes[4] = i;
  80.                     }
  81.                     result->indexes[5] = j + k;
  82.                     result->count = lengthOfHorizontal + lengthOfVertical;
  83.                     // Используем мьютекс для записи промежуточного результата в общую очередь
  84.                     // Лочим поток
  85.                     pthread_mutex_lock(&mutex);
  86.                     tail->result = *result;
  87.                     tail->threadNumber = info->threadNumber;
  88.                     // Выделяем место для следующей операции
  89.                     new = (struct TaskQueue *) malloc(sizeof(struct TaskQueue));
  90.                     tail->next = new;
  91.                     // Заменяем последний элемент на текущий
  92.                     tail = new;
  93.                     // Разблокируем поток
  94.                     pthread_mutex_unlock(&mutex);
  95.                 }
  96.                 k += info->deltaY;
  97.             }
  98.         }
  99.     }
  100.     return (void *) result;
  101. }
  102.  
  103. void find_g(int matrix[ROWS][COLS]) {
  104.     // Инициализация очереди операций и мьютекса
  105.     head = (struct TaskQueue *) malloc(sizeof(struct TaskQueue));
  106.     tail = head;
  107.     pthread_mutex_init(&mutex, NULL);
  108.  
  109.     int maxCount = 0;
  110.     int coords[] = {0, 0, 0, 0, 0, 0};
  111.     struct ThreadInfo rightUpper, leftUpper, leftLower, rightLower;
  112.     struct ThreadResult *rightUpperResult, *leftUpperResult, *leftLowerResult, *rightLowerResult;
  113.     memcpy(rightUpper.matrix, matrix, ROWS * COLS * sizeof(int));
  114.     memcpy(leftUpper.matrix, matrix, ROWS * COLS * sizeof(int));
  115.     memcpy(leftLower.matrix, matrix, ROWS * COLS * sizeof(int));
  116.     memcpy(rightLower.matrix, matrix, ROWS * COLS * sizeof(int));
  117.     rightUpper.deltaX = 1;
  118.     rightUpper.deltaY = -1;
  119.     rightUpper.threadNumber = 1;
  120.  
  121.     leftUpper.deltaX = -1;
  122.     leftUpper.deltaY = -1;
  123.     leftUpper.threadNumber = 2;
  124.  
  125.     leftLower.deltaX = -1;
  126.     leftLower.deltaY = 1;
  127.     leftLower.threadNumber = 3;
  128.  
  129.     rightLower.deltaX = 1;
  130.     rightLower.deltaY = 1;
  131.     rightLower.threadNumber = 4;
  132.  
  133.     pthread_t thread1, thread2, thread3, thread4;
  134.     // По сути, каждый отдельный поток считает лучший результат для своего угла.
  135.     // После этого основной поток (эта функция) собирает данные воедино и выводит результат
  136.     pthread_create(&thread1, NULL, &get_values, &rightUpper);
  137.     pthread_create(&thread2, NULL, &get_values, &leftUpper);
  138.     pthread_create(&thread3, NULL, &get_values, &leftLower);
  139.     pthread_create(&thread4, NULL, &get_values, &rightLower);
  140.     pthread_join(thread1, (void **) &rightUpperResult);
  141.     pthread_join(thread2, (void **) &leftUpperResult);
  142.     pthread_join(thread3, (void **) &leftLowerResult);
  143.     pthread_join(thread4, (void **) &rightLowerResult);
  144.     if (rightUpperResult->count > maxCount) {
  145.         maxCount = rightUpperResult->count;
  146.         memcpy(coords, rightUpperResult->indexes, sizeof(rightUpperResult->indexes));
  147.     }
  148.     if (leftUpperResult->count > maxCount) {
  149.         maxCount = leftUpperResult->count;
  150.         memcpy(coords, leftUpperResult->indexes, sizeof(leftUpperResult->indexes));
  151.     }
  152.     if (leftLowerResult->count > maxCount) {
  153.         maxCount = leftLowerResult->count;
  154.         memcpy(coords, leftLowerResult->indexes, sizeof(leftLowerResult->indexes));
  155.     }
  156.     if (rightLowerResult->count > maxCount) {
  157.         maxCount = rightLowerResult->count;
  158.         memcpy(coords, rightLowerResult->indexes, sizeof(rightLowerResult->indexes));
  159.     }
  160.     for (int i = 0; i < 6; i++) {
  161.         printf("%d ", coords[i]);
  162.     }
  163.     printf("\nTask queue:\n");
  164.     struct TaskQueue *current = head;
  165.     while (current->next != NULL) {
  166.         printf("Thread %d: ", current->threadNumber);
  167.         for (int i = 0; i < 6; i++) {
  168.             printf("%d ", current->result.indexes[i]);
  169.         }
  170.         printf("\n");
  171.         current = current->next;
  172.     }
  173. }
  174.  
  175. int main() {
  176. //    printf("Hello, World!\n");
  177.     int arr[ROWS][COLS] = {{0, 2, 0, 2, 0},
  178.                            {0, 1, 1, 1, 0},
  179.                            {2, 0, 2, 1, 1},
  180.                            {0, 2, 0, 1, 1}};
  181. //    fill_matrix(arr);
  182.     print_matrix(arr);
  183.     find_g(arr);
  184.     return 0;
  185. }
  186.  
Advertisement
Comments
  • artmexbet
    11 days
    # text 1.44 KB | 0 0
    1. Короче, я переписал хуйню так, как тебе сказали на защите прошлой работы (теперь в потоки выкидываются циклы для просчёта каждого уголка отдельно, типа, один считает только для левого верхнего и т.д.). В очередь (по заданию) промежуточная инфа с каждого потока. Я не ебу, почему они выводятся всё равно по порядку так, будто никакие мьютексы не разлочиваются (хуй знает, всё, как в пдфке), но вроде должно всё работать. Так вот, каждый поток считает у себя максимальное количество элементов, которое может найти в своём конкретном уголке и на каждой смене максимума (если мы нашли элемент больше, чем был найден до этого) выкидывает инфу об этом в очередь промежуточных вычислений. Вот как-то так.
    2.  
    3. Я, на самом деле, не уверен, что именно это нужно было делать, но я заюзал семафоры. Там просто довольно размытое ТЗ))
Add Comment
Please, Sign In to add comment
Advertisement