Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <pthread.h>
- #include <string.h>
- #define ROWS 4
- #define COLS 5
- struct ThreadResult {
- int count;
- int indexes[6];
- };
- struct TaskQueue {
- struct TaskQueue *next;
- struct ThreadResult result;
- int threadNumber;
- };
- struct ThreadInfo {
- int matrix[ROWS][COLS];
- int deltaX;
- int deltaY;
- int threadNumber;
- };
- void fill_matrix(int array[ROWS][COLS]) {
- srand(time(NULL));
- for (int i = 0; i < ROWS; i++) {
- for (int j = 0; j < COLS; j++) {
- array[i][j] = 1 + rand() % 3;
- }
- }
- }
- void print_matrix(int array[ROWS][COLS]) {
- for (int i = 0; i < ROWS; i++) {
- for (int j = 0; j < COLS; j++) {
- printf("%d ", array[i][j]);
- }
- printf("\n");
- }
- }
- pthread_mutex_t mutex;
- struct TaskQueue *head = NULL;
- struct TaskQueue *new = NULL;
- struct TaskQueue *tail = NULL;
- void *get_values(void *info_) {
- struct ThreadInfo *info = (struct ThreadInfo *) info_;
- struct ThreadResult *result = (struct ThreadResult *) malloc(sizeof(struct ThreadResult));
- result->count = 0;
- for (int i = 0; i < ROWS; i++) {
- for (int j = 0; j < COLS; j++) {
- int k = 0;
- int lengthOfHorizontal = 0; // Сюда сохраняем длину повторяющихся символов в строке
- while (0 < j + k && j + k < COLS && info->matrix[i][j + k] == info->matrix[i][j]) {
- lengthOfHorizontal++;
- int l = 0;
- int lengthOfVertical = 0; // Сюда сохраняем длину повторяющихся символов в столбце
- while (0 < i + l && i + l < ROWS && info->matrix[i + l][j + k] == info->matrix[i][j + k]) {
- lengthOfVertical++;
- l += info->deltaX;
- }
- if (lengthOfHorizontal + lengthOfVertical > result->count) {
- result->indexes[0] = i;
- result->indexes[1] = j;
- result->indexes[2] = i;
- result->indexes[3] = j + k;
- if (l != 0) {
- result->indexes[4] = i + l - 1 * info->deltaX;
- // Если в l добавлялись элементы, значение в ней будет на единицу больше (или меньше,
- // в зависимости от deltaX) из-за того, что мы сначала проверяем, а уже затем увеличиваем l
- // в цикле while выше
- } else {
- // Если же l = 0, вычитать ничего не нужно, нужно лишь записать эту же строку в нужный индекс
- result->indexes[4] = i;
- }
- result->indexes[5] = j + k;
- result->count = lengthOfHorizontal + lengthOfVertical;
- // Используем мьютекс для записи промежуточного результата в общую очередь
- // Лочим поток
- pthread_mutex_lock(&mutex);
- tail->result = *result;
- tail->threadNumber = info->threadNumber;
- // Выделяем место для следующей операции
- new = (struct TaskQueue *) malloc(sizeof(struct TaskQueue));
- tail->next = new;
- // Заменяем последний элемент на текущий
- tail = new;
- // Разблокируем поток
- pthread_mutex_unlock(&mutex);
- }
- k += info->deltaY;
- }
- }
- }
- return (void *) result;
- }
- void find_g(int matrix[ROWS][COLS]) {
- // Инициализация очереди операций и мьютекса
- head = (struct TaskQueue *) malloc(sizeof(struct TaskQueue));
- tail = head;
- pthread_mutex_init(&mutex, NULL);
- int maxCount = 0;
- int coords[] = {0, 0, 0, 0, 0, 0};
- struct ThreadInfo rightUpper, leftUpper, leftLower, rightLower;
- struct ThreadResult *rightUpperResult, *leftUpperResult, *leftLowerResult, *rightLowerResult;
- memcpy(rightUpper.matrix, matrix, ROWS * COLS * sizeof(int));
- memcpy(leftUpper.matrix, matrix, ROWS * COLS * sizeof(int));
- memcpy(leftLower.matrix, matrix, ROWS * COLS * sizeof(int));
- memcpy(rightLower.matrix, matrix, ROWS * COLS * sizeof(int));
- rightUpper.deltaX = 1;
- rightUpper.deltaY = -1;
- rightUpper.threadNumber = 1;
- leftUpper.deltaX = -1;
- leftUpper.deltaY = -1;
- leftUpper.threadNumber = 2;
- leftLower.deltaX = -1;
- leftLower.deltaY = 1;
- leftLower.threadNumber = 3;
- rightLower.deltaX = 1;
- rightLower.deltaY = 1;
- rightLower.threadNumber = 4;
- pthread_t thread1, thread2, thread3, thread4;
- // По сути, каждый отдельный поток считает лучший результат для своего угла.
- // После этого основной поток (эта функция) собирает данные воедино и выводит результат
- pthread_create(&thread1, NULL, &get_values, &rightUpper);
- pthread_create(&thread2, NULL, &get_values, &leftUpper);
- pthread_create(&thread3, NULL, &get_values, &leftLower);
- pthread_create(&thread4, NULL, &get_values, &rightLower);
- pthread_join(thread1, (void **) &rightUpperResult);
- pthread_join(thread2, (void **) &leftUpperResult);
- pthread_join(thread3, (void **) &leftLowerResult);
- pthread_join(thread4, (void **) &rightLowerResult);
- if (rightUpperResult->count > maxCount) {
- maxCount = rightUpperResult->count;
- memcpy(coords, rightUpperResult->indexes, sizeof(rightUpperResult->indexes));
- }
- if (leftUpperResult->count > maxCount) {
- maxCount = leftUpperResult->count;
- memcpy(coords, leftUpperResult->indexes, sizeof(leftUpperResult->indexes));
- }
- if (leftLowerResult->count > maxCount) {
- maxCount = leftLowerResult->count;
- memcpy(coords, leftLowerResult->indexes, sizeof(leftLowerResult->indexes));
- }
- if (rightLowerResult->count > maxCount) {
- maxCount = rightLowerResult->count;
- memcpy(coords, rightLowerResult->indexes, sizeof(rightLowerResult->indexes));
- }
- for (int i = 0; i < 6; i++) {
- printf("%d ", coords[i]);
- }
- printf("\nTask queue:\n");
- struct TaskQueue *current = head;
- while (current->next != NULL) {
- printf("Thread %d: ", current->threadNumber);
- for (int i = 0; i < 6; i++) {
- printf("%d ", current->result.indexes[i]);
- }
- printf("\n");
- current = current->next;
- }
- }
- int main() {
- // printf("Hello, World!\n");
- int arr[ROWS][COLS] = {{0, 2, 0, 2, 0},
- {0, 1, 1, 1, 0},
- {2, 0, 2, 1, 1},
- {0, 2, 0, 1, 1}};
- // fill_matrix(arr);
- print_matrix(arr);
- find_g(arr);
- return 0;
- }
Advertisement
Comments
-
- Короче, я переписал хуйню так, как тебе сказали на защите прошлой работы (теперь в потоки выкидываются циклы для просчёта каждого уголка отдельно, типа, один считает только для левого верхнего и т.д.). В очередь (по заданию) промежуточная инфа с каждого потока. Я не ебу, почему они выводятся всё равно по порядку так, будто никакие мьютексы не разлочиваются (хуй знает, всё, как в пдфке), но вроде должно всё работать. Так вот, каждый поток считает у себя максимальное количество элементов, которое может найти в своём конкретном уголке и на каждой смене максимума (если мы нашли элемент больше, чем был найден до этого) выкидывает инфу об этом в очередь промежуточных вычислений. Вот как-то так.
- Я, на самом деле, не уверен, что именно это нужно было делать, но я заюзал семафоры. Там просто довольно размытое ТЗ))
Add Comment
Please, Sign In to add comment
Advertisement