Initial commit
This commit is contained in:
commit
b365b81639
8
CMakeLists.txt
Normal file
8
CMakeLists.txt
Normal file
@ -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)
|
||||
86
task1.c
Normal file
86
task1.c
Normal file
@ -0,0 +1,86 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
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;
|
||||
}
|
||||
95
task2.c
Normal file
95
task2.c
Normal file
@ -0,0 +1,95 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
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;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user