From b365b816397776bda080abc5a1dea9e7370e765c Mon Sep 17 00:00:00 2001 From: gandc Date: Thu, 24 Apr 2025 01:15:54 +0300 Subject: [PATCH] Initial commit --- CMakeLists.txt | 8 +++++ task1.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ task2.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 task1.c create mode 100644 task2.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..60a81e8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.10) +project(search_barrier) + +find_package(Threads REQUIRED) +link_libraries(Threads::Threads) + +add_executable(task1 task1.c) +add_executable(task2 task2.c) diff --git a/task1.c b/task1.c new file mode 100644 index 0000000..e6f8abc --- /dev/null +++ b/task1.c @@ -0,0 +1,86 @@ +#include +#include +#include + +typedef struct { + int thread_id; + int start, end; + int *array; + int target; +} ThreadData; + +int THREAD_COUNT; +int *local_results; +int global_result = -1; +pthread_barrier_t barrier; + +void *search_first(void *arg) { + ThreadData *d = (ThreadData*)arg; + int found = -1; + for (int i = d->start; i < d->end; i++) { + if (d->array[i] == d->target) { + found = i; + break; + } + } + local_results[d->thread_id] = found; + + int rc = pthread_barrier_wait(&barrier); + if (rc == PTHREAD_BARRIER_SERIAL_THREAD) { + int min_idx = -1; + for (int i = 0; i < THREAD_COUNT; i++) { + if (local_results[i] != -1 && + (min_idx == -1 || local_results[i] < min_idx)) { + min_idx = local_results[i]; + } + } + global_result = min_idx; + } + return NULL; +} + +int main() { + int n, target; + printf("Введите N и искомое значение: "); + if (scanf("%d %d", &n, &target) != 2) { + fprintf(stderr, "Ошибка ввода\n"); + return EXIT_FAILURE; + } + int *array = malloc(n * sizeof(int)); + printf("Введите %d элементов массива: ", n); + for (int i = 0; i < n; i++) scanf("%d", &array[i]); + + printf("Введите число потоков: "); + scanf("%d", &THREAD_COUNT); + + local_results = malloc(THREAD_COUNT * sizeof(int)); + pthread_barrier_init(&barrier, NULL, THREAD_COUNT); + + pthread_t threads[THREAD_COUNT]; + ThreadData tdata[THREAD_COUNT]; + int chunk = n / THREAD_COUNT; + + for (int i = 0; i < THREAD_COUNT; i++) { + tdata[i] = (ThreadData){ + .thread_id = i, + .start = i * chunk, + .end = (i == THREAD_COUNT - 1 ? n : (i+1)*chunk), + .array = array, + .target = target + }; + pthread_create(&threads[i], NULL, search_first, &tdata[i]); + } + + for (int i = 0; i < THREAD_COUNT; i++) + pthread_join(threads[i], NULL); + + if (global_result != -1) + printf("Первое вхождение %d на индексе %d\n", target, global_result); + else + printf("Значение %d не найдено\n", target); + + pthread_barrier_destroy(&barrier); + free(array); + free(local_results); + return EXIT_SUCCESS; +} diff --git a/task2.c b/task2.c new file mode 100644 index 0000000..fe5bf46 --- /dev/null +++ b/task2.c @@ -0,0 +1,95 @@ +#include +#include +#include + +typedef struct { + int thread_id; + int start, end; + int *array; + int target; + int *counts; + int **idxs; +} ThreadData; + +int THREAD_COUNT; +pthread_barrier_t barrier; + +void *search_all(void *arg) { + ThreadData *d = (ThreadData*)arg; + int local_count = 0; + int capacity = d->end - d->start; + int *local_idxs = malloc(capacity * sizeof(int)); + + for (int i = d->start; i < d->end; i++) { + if (d->array[i] == d->target) + local_idxs[local_count++] = i; + } + d->counts[d->thread_id] = local_count; + d->idxs[d->thread_id] = local_idxs; + + int rc = pthread_barrier_wait(&barrier); + if (rc == PTHREAD_BARRIER_SERIAL_THREAD) { + // общее число вхождений + int total = 0; + for (int i = 0; i < THREAD_COUNT; i++) + total += d->counts[i]; + + printf("Всего найдено: %d\n", total); + if (total > 0) { + printf("Индексы (возрастание): "); + for (int i = 0; i < THREAD_COUNT; i++) { + for (int j = 0; j < d->counts[i]; j++) + printf("%d ", d->idxs[i][j]); + free(d->idxs[i]); + } + printf("\n"); + } + } + return NULL; +} + +int main() { + int n, target; + printf("Введите N и искомое значение: "); + if (scanf("%d %d", &n, &target) != 2) { + fprintf(stderr, "Ошибка ввода\n"); + return EXIT_FAILURE; + } + int *array = malloc(n * sizeof(int)); + printf("Введите %d элементов массива: ", n); + for (int i = 0; i < n; i++) scanf("%d", &array[i]); + + printf("Введите число потоков: "); + scanf("%d", &THREAD_COUNT); + + // структуры + int *counts = calloc(THREAD_COUNT, sizeof(int)); + int **idxs = malloc(THREAD_COUNT * sizeof(int*)); + pthread_barrier_init(&barrier, NULL, THREAD_COUNT); + + pthread_t threads[THREAD_COUNT]; + ThreadData tdata[THREAD_COUNT]; + int chunk = n / THREAD_COUNT; + + for (int i = 0; i < THREAD_COUNT; i++) { + tdata[i] = (ThreadData){ + .thread_id = i, + .start = i*chunk, + .end = (i == THREAD_COUNT-1 ? n : (i+1)*chunk), + .array = array, + .target = target, + .counts = counts, + .idxs = idxs + }; + pthread_create(&threads[i], NULL, search_all, &tdata[i]); + } + + for (int i = 0; i < THREAD_COUNT; i++) + pthread_join(threads[i], NULL); + + pthread_barrier_destroy(&barrier); + free(array); + free(counts); + free(idxs); + return EXIT_SUCCESS; +}