Compare commits

3 Commits

Author SHA1 Message Date
Fabio Scotto di Santolo
f4a46ce9f1 Exercise 8.32 2024-10-10 18:37:22 +02:00
Fabio Scotto di Santolo
df65f88779 Cancel thread tasks using semaphore 2024-09-18 15:09:38 +02:00
Fabio Scotto di Santolo
554b36e0f3 Cancel threads task with signal 2024-09-18 11:17:13 +02:00
10 changed files with 190 additions and 0 deletions

1
.gitignore vendored
View File

@@ -57,5 +57,6 @@ dkms.conf
# User specific
/kernel-sign
.vscode/
# End of https://www.toptal.com/developers/gitignore/api/c

View File

@@ -0,0 +1 @@
cancel_threads

View File

@@ -0,0 +1,18 @@
CC=gcc
CFLAGS=-o cancel_threads -Wall -lpthread -lc -D_GNU_SOURCE
SRCS=main.c
.DEFAULT_GOAL := build
build:
$(CC) $(CFLAGS) -fsanitize=address -static-libasan $(SRCS)
release:
$(CC) $(CFLAGS) $(SRCS)
debug:
$(CC) $(CFLAGS) -fsanitize=address -static-libasan -ggdb $(SRCS)
gdb -q cancel_threads
clean:
rm -f cancel_threads

View File

@@ -0,0 +1,66 @@
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define THREAD_COUNT 10
void *expensive_task(void *);
void send_finish_signal(void *);
void handler(int);
pthread_t main_thread;
pthread_t threads[THREAD_COUNT];
int main(void) {
main_thread = pthread_self();
// Register handler for SIGCHLD signal
signal(SIGCHLD, handler);
pthread_attr_t attr;
if (pthread_attr_init(&attr) != 0) {
perror("Error");
return EXIT_FAILURE;
}
int n[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
n[i] = i;
printf("Create thread number %d\n", i);
pthread_create(&threads[i], &attr, expensive_task, (void *)&n[i]);
}
for (int i = 0; i < THREAD_COUNT; i++) {
printf("Waiting thread number %d...\n", i);
pthread_join(threads[i], NULL);
printf("Thread %d joined\n", i);
}
return EXIT_SUCCESS;
}
void handler(int sig) {
printf("Caught signal %d\n", sig);
for (int i = 0; i < THREAD_COUNT; i++) {
pthread_cancel(threads[i]);
}
}
void send_finish_signal(void *args) {
int *id = (int *)args;
printf("Thread %d send SIGCHLD signal\n", *id);
pthread_kill(main_thread, SIGCHLD);
printf("Thread %d cleanup handle is done\n", *id);
}
void *expensive_task(void *args) {
pthread_cleanup_push(send_finish_signal, args);
const int tid = *((int *)args);
printf("Thread %d are running...\n", tid);
sleep(rand() % 31);
printf("Thread %d terminated!!!\n", tid);
pthread_cleanup_pop(1);
pthread_exit(0);
}

View File

@@ -0,0 +1 @@
cancel_threads

View File

@@ -0,0 +1,18 @@
CC=gcc
CFLAGS=-o cancel_threads -Wall -lpthread -lrt
SRCS=main.c
.DEFAULT_GOAL := build
build:
$(CC) $(CFLAGS) -fsanitize=address -static-libasan $(SRCS)
release:
$(CC) $(CFLAGS) $(SRCS)
debug:
$(CC) $(CFLAGS) -fsanitize=address -static-libasan -ggdb $(SRCS)
gdb -q cancel_threads
clean:
rm -f cancel_threads

View File

@@ -0,0 +1,54 @@
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define THREAD_COUNT 10
void *expensive_task(void *);
sem_t semaphore;
int main(void) {
sem_init(&semaphore, 0, 0);
pthread_attr_t attr;
if (pthread_attr_init(&attr) != 0) {
perror("Error");
return EXIT_FAILURE;
}
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int n[THREAD_COUNT];
pthread_t threads[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
n[i] = i;
printf("Create thread number %d\n", i);
pthread_create(&threads[i], &attr, expensive_task, (void *)&n[i]);
}
printf("Waiting semaphore...\n");
sem_wait(&semaphore);
printf("Unlock semaphore\n");
for (int i = 0; i < THREAD_COUNT; i++) {
printf("Cancel thread %d\n", i);
pthread_cancel(threads[i]);
}
sem_destroy(&semaphore);
return EXIT_SUCCESS;
}
void *expensive_task(void *args) {
const int tid = *((int *)args);
printf("Thread %d are running...\n", tid);
sleep(rand() % 31);
printf("Thread %d terminated!!!\n", tid);
sem_post(&semaphore);
pthread_exit(0);
}

1
chp8_memory/mem/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
mem

11
chp8_memory/mem/Makefile Normal file
View File

@@ -0,0 +1,11 @@
CC=gcc
CFLAGS=-Wall -o mem
SRCS=main.c
build:
$(CC) $(CFLAGS) $(SRCS)
debug:
$(CC) $(CFLAGS) -fsanitize=address -static-libasan -ggdb $(SRCS)
gdb -q mem
clean:
rm -f mem

19
chp8_memory/mem/main.c Normal file
View File

@@ -0,0 +1,19 @@
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: mem <ADDRESS>\n");
return EXIT_FAILURE;
}
const unsigned long n = atoi(argv[1]);
const unsigned long page = n >> 12; // equal to n / 2^12
const unsigned long offset = n - (page << 12); // equal to n - (page * 2^12)
printf("The address %lu contains:\n", n);
printf("page number = %lu\n", page);
printf("offset = %lu\n", offset);
return EXIT_SUCCESS;
}