Added exercises on thread arguments

This commit is contained in:
Fabio Scotto di Santolo
2024-08-30 15:55:28 +02:00
parent b941fca02a
commit ee1c25488a
4 changed files with 322 additions and 0 deletions

101
threads/ex421.c Normal file
View File

@@ -0,0 +1,101 @@
#include <limits.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define OPERATIONS 3
#define MIN(a, b) a > b ? b : a
#define MAX(a, b) a < b ? b : a
void *min(void *);
void *avg(void *);
void *max(void *);
typedef void *(*pthread_fn_t)(void *);
typedef struct __THREAD_DATA__ {
int *numbers;
int size;
} thread_data_t;
int minimum = INT_MAX;
int maximum = INT_MIN;
int average = 0;
int main(int argc, char *argv[]) {
if (argc < 2) {
perror("Usage: statistic NUMBERS...\n");
exit(EXIT_FAILURE);
}
const int size = argc - 1;
int *numbers = (int *)calloc(size, sizeof(int));
for (int i = 1; i < argc; i++) {
numbers[i - 1] = atoi(argv[i]);
}
const thread_data_t tdata = {.numbers = numbers, .size = size};
const pthread_fn_t ops[OPERATIONS] = {min, max, avg};
pthread_attr_t attr;
pthread_t threads[OPERATIONS];
pthread_attr_init(&attr);
for (size_t i = 0; i < OPERATIONS; i++) {
pthread_create(&threads[i], &attr, ops[i], (void *)&tdata);
}
for (int i = 0; i < OPERATIONS; i++) {
pthread_join(threads[i], NULL);
}
printf("Summary:\n");
printf("The average value is %d\n", average);
printf("The minimum value is %d\n", minimum);
printf("The maximum value is %d\n", maximum);
free(numbers);
numbers = NULL;
return EXIT_SUCCESS;
}
void *min(void *args) {
const thread_data_t *tdata = (thread_data_t *)args;
const int *numbers = tdata->numbers;
const int size = tdata->size;
for (int i = 0; i < size; i++) {
minimum = MIN(minimum, numbers[i]);
}
pthread_exit(0);
}
void *max(void *args) {
const thread_data_t *tdata = (thread_data_t *)args;
const int *numbers = tdata->numbers;
const int size = tdata->size;
for (int i = 0; i < size; i++) {
maximum = MAX(maximum, numbers[i]);
}
pthread_exit(0);
}
int sum(const int *values, const int n) {
int sum = 0;
for (int i = 0; i < n; i++) {
sum += values[i];
}
return sum;
}
void *avg(void *args) {
const thread_data_t *tdata = (thread_data_t *)args;
const int *numbers = tdata->numbers;
const int size = tdata->size;
const int total = sum(numbers, size);
average = total / size;
pthread_exit(0);
}

56
threads/ex424.c Normal file
View File

@@ -0,0 +1,56 @@
#define _GNU_SOURCE
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
bool prime(int n);
void *primes(void *);
const int thread_err = 1;
int main(int argc, char *argv[]) {
if (argc < 2) {
perror("Usage: prime NUMBER\n");
exit(EXIT_SUCCESS);
}
const int n = atoi(argv[1]);
pthread_attr_t attr;
pthread_t thread;
pthread_attr_init(&attr);
pthread_create(&thread, &attr, primes, (void *)&n);
pthread_join(thread, NULL);
return EXIT_SUCCESS;
}
void *primes(void *args) {
printf("Thread %d calculate primes number\n", gettid());
const int *n = (int *)args;
if (*n <= 1) {
perror("Is not possible calculate prime numbers for number less or equal "
"than 1\n");
pthread_exit((void *)&thread_err);
}
for (int i = 2; i <= *n; i++) {
if (prime(i)) {
printf("%d ", i);
}
}
printf("\n");
pthread_exit(0);
}
bool prime(int n) {
for (int i = 2; i < n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}

57
threads/ex426.c Normal file
View File

@@ -0,0 +1,57 @@
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long long int bigint_t;
void *fibonacci(void *);
bigint_t *numbers;
int main(int argc, char *argv[]) {
if (argc < 2) {
perror("USAGE: fibonacci NUMBER\n");
exit(EXIT_FAILURE);
}
const int n = atoi(argv[1]);
numbers = (bigint_t *)calloc(n, sizeof(bigint_t));
pthread_attr_t attr;
pthread_t thread;
pthread_attr_init(&attr);
pthread_create(&thread, &attr, fibonacci, (void *)&n);
pthread_join(thread, NULL);
printf("Fibonacci of %d:\n", n);
for (int i = 0; i < n; i++) {
printf("%llu ", numbers[i]);
}
printf("\n");
free(numbers);
numbers = NULL;
return EXIT_SUCCESS;
}
void *fibonacci(void *args) {
const int *n = (int *)args;
bigint_t first = 0, second = 1;
if (*n >= 1) {
numbers[0] = first;
}
if (*n >= 2) {
numbers[1] = second;
}
for (int i = 2; i < *n; i++) {
const bigint_t third = first + second;
first = second;
second = third;
numbers[i] = third;
}
pthread_exit(0);
}

108
threads/project2.c Normal file
View File

@@ -0,0 +1,108 @@
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROUNDUP(a, b) (a + b - 1) / b
void *sort(void *);
void *merge(void *);
typedef struct __THREAD_DATA__ {
int *array;
int size;
} thread_data_t;
typedef struct __MERGE_DATA__ {
thread_data_t tdata1;
thread_data_t tdata2;
} merge_data_t;
int *original_array;
int *sorted_array;
int main(int argc, char *argv[]) {
if (argc < 2) {
perror("USAGE: sortt NUMBERS...\n");
exit(EXIT_FAILURE);
}
const int size = argc - 1;
original_array = (int *)calloc(size, sizeof(int));
for (int i = 1; i < argc; i++) {
original_array[i - 1] = atoi(argv[i]);
}
int size1 = ROUNDUP(size, 2);
int size2 = size - size1;
int *slice1 = &original_array[0];
int *slice2 = &original_array[size2 + 1];
const thread_data_t tdata1 = {.array = slice1, .size = size1};
const thread_data_t tdata2 = {.array = slice2, .size = size2};
pthread_attr_t attr;
pthread_t threads[3];
pthread_attr_init(&attr);
pthread_create(&threads[0], &attr, sort, (void *)&tdata1);
pthread_create(&threads[1], &attr, sort, (void *)&tdata2);
for (int i = 0; i < 2; i++) {
pthread_join(threads[i], NULL);
}
sorted_array = (int *)calloc(size, sizeof(int));
merge_data_t mdata = {.tdata1 = tdata1, .tdata2 = tdata2};
pthread_create(&threads[2], &attr, merge, (void *)&mdata);
pthread_join(threads[2], NULL);
for (int i = 0; i < size; i++) {
printf("%d ", sorted_array[i]);
}
printf("\n");
free(original_array);
original_array = NULL;
free(sorted_array);
sorted_array = NULL;
return EXIT_SUCCESS;
}
void swap(int *array, int a, int b) {
int tmp = array[a];
array[a] = array[b];
array[b] = tmp;
}
void selection_sort(int *arr, int size) {
for (int i = 0; i < size - 1; i++) {
int min_idx = i;
for (int j = i + 1; j < size; j++) {
if (arr[j] < arr[min_idx]) {
min_idx = j;
}
}
swap(arr, min_idx, i);
}
}
void *sort(void *args) {
const thread_data_t *tdata = (thread_data_t *)args;
selection_sort(tdata->array, tdata->size);
pthread_exit(0);
}
void *merge(void *args) {
const merge_data_t *mdata = (merge_data_t *)args;
const thread_data_t tdata1 = mdata->tdata1;
const thread_data_t tdata2 = mdata->tdata2;
const int size = tdata1.size + tdata2.size;
for (int i = 0; i < tdata1.size; i++) {
sorted_array[i] = tdata1.array[i];
}
for (int i = tdata1.size; i < size; i++) {
sorted_array[i] = tdata2.array[i - tdata1.size];
}
selection_sort(sorted_array, size);
pthread_exit(0);
}