Refactoring in chapters
This commit is contained in:
31
threads_chp4/ex417.c
Normal file
31
threads_chp4/ex417.c
Normal file
@@ -0,0 +1,31 @@
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int value = 0;
|
||||
void *runner(void *param);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
pid_t pid;
|
||||
pthread_t tid;
|
||||
pthread_attr_t attr;
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid == 0) {
|
||||
pthread_attr_init(&attr);
|
||||
pthread_create(&tid, &attr, runner, NULL);
|
||||
pthread_join(tid, NULL);
|
||||
printf("CHILD: value = %d\n", value);
|
||||
} else if (pid > 0) {
|
||||
wait(NULL);
|
||||
printf("PARENT: value = %d\n", value);
|
||||
}
|
||||
}
|
||||
|
||||
void *runner(void *param) {
|
||||
value = 5;
|
||||
pthread_exit(0);
|
||||
}
|
||||
101
threads_chp4/ex421.c
Normal file
101
threads_chp4/ex421.c
Normal 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_chp4/ex424.c
Normal file
56
threads_chp4/ex424.c
Normal 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_chp4/ex426.c
Normal file
57
threads_chp4/ex426.c
Normal 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);
|
||||
}
|
||||
70
threads_chp4/pid_manager.c
Normal file
70
threads_chp4/pid_manager.c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "pid_manager.h"
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define MIN_PID 300
|
||||
#define MAX_PID 5000
|
||||
#define SIZE (MAX_PID - MIN_PID + 1)
|
||||
|
||||
bool pids[SIZE];
|
||||
|
||||
void *runner(void *param);
|
||||
|
||||
int allocate_map(void) {
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
pids[i] = false;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int allocate_pid(void) {
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
if (!pids[i]) {
|
||||
pids[i] = true;
|
||||
return i + MIN_PID;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void release_pid(int pid) {
|
||||
if (pid >= MIN_PID && pid <= MAX_PID) {
|
||||
pids[pid - MIN_PID] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void *runner(void *param) {
|
||||
const pid_t self = gettid();
|
||||
const int pid = allocate_pid();
|
||||
printf("Run thread %d handle PID %d.\n", self, pid);
|
||||
sleep(rand() % 31);
|
||||
release_pid(pid);
|
||||
printf("Thread %d ended\n", self);
|
||||
pthread_exit(0);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
const int thread_count = 100;
|
||||
pthread_t threads[thread_count];
|
||||
|
||||
if (!allocate_map()) {
|
||||
perror("Failed to allocate PID Manager\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < thread_count; i++) {
|
||||
printf("Created thread %d\n", i);
|
||||
pthread_create(&threads[i], NULL, runner, NULL);
|
||||
}
|
||||
|
||||
for (int i = 0; i < thread_count; i++) {
|
||||
printf("Waiting thread %d\n", i);
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
16
threads_chp4/pid_manager.h
Normal file
16
threads_chp4/pid_manager.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#if !defined(__PID_MANGER_H__)
|
||||
#define __PID_MANGER_H__
|
||||
#define _GNU_SOURCE
|
||||
|
||||
// Crea e inizializza una struttura per rappresentare i pid;
|
||||
// restituisce -1 in caso di insuccesso e 1 in caso di successo.
|
||||
int allocate_map(void);
|
||||
|
||||
// Alloca e restituisce un pid, restituisce -1 se non è possibile
|
||||
// assegnare un PID (tutti i pid sono in uso).
|
||||
int allocate_pid(void);
|
||||
|
||||
// Rilascia un pid
|
||||
void release_pid(int pid);
|
||||
|
||||
#endif
|
||||
91
threads_chp4/project2.c
Normal file
91
threads_chp4/project2.c
Normal file
@@ -0,0 +1,91 @@
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.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;
|
||||
}
|
||||
|
||||
int compare(const void *a, const void *b) { return (*(int *)a) - *((int *)b); }
|
||||
|
||||
void *sort(void *args) {
|
||||
const thread_data_t *tdata = (thread_data_t *)args;
|
||||
qsort(tdata->array, tdata->size, sizeof(int), compare);
|
||||
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];
|
||||
}
|
||||
qsort(sorted_array, size, sizeof(int), compare);
|
||||
pthread_exit(0);
|
||||
}
|
||||
Reference in New Issue
Block a user