Skip to content
Snippets Groups Projects
Commit 883299a0 authored by Mactavish's avatar Mactavish
Browse files

add semaphore exercise

parent 7e028c8c
No related branches found
No related tags found
No related merge requests found
PROG = main
OBJECTS = main.o semaphore.o
CC = gcc
CFLAGS = -Wall -std=c11 -pthread
CFLAGS += -I. # add the current directory to the include path
.Phone: all
all: clean $(PROG) # build and run the program
./$(PROG)
$(PROG): $(OBJECTS) # link the object files into a binary
$(CC) $(CFLAGS) $^ -o $@
$(OBJECTS): %.o: %.c semaphore.h # compile the source files into object files
$(CC) $(CFLAGS) -c $<
.PHONY: clean
clean: # remove the object files and the binary
rm -f $(OBJECTS) $(PROG)
# Semaphore implementation
Here is a small exercise that helps you understand semaphore and conditional variables better.
## Instructions
First, go through all function declarations in `semaphore.h`. Then, go through `main.c` to see how these functions are used in the test program.
You will need to implement the following functions:
- `sem_init`: initialize the internal data for your semaphore implementation
- `sem_wait`: allow the access of a thread into the critical section and decrement the counter, or put the thread into a waiting queue.
- `sem_post`: increment the counter by 1, and signal the waiting threads in the queue if any.
- `sem_destory`: clean up all the data you've used.
## Hints
Read the man page about [condition variables](https://man7.org/linux/man-pages/man3/pthread_cond_wait.3p.html)
## Build
```bash
# build and run the executable
make
# clean all compilation files
make clean
```
#include <stdio.h>
#include <unistd.h>
#include "semaphore.h"
// Example usage
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
semaphore sem;
void* thread_function(void* arg) {
int id = *((int*)arg);
int i = 5;
sem_wait(&sem);
pthread_mutex_lock(&mutex);
printf("Thread %d enters\n", id);
pthread_mutex_unlock(&mutex);
sleep(1);
pthread_mutex_lock(&mutex);
printf("Thread %d quits\n", id);
pthread_mutex_unlock(&mutex);
sem_post(&sem);
pthread_exit(NULL);
}
int main() {
int num_threads = 10;
pthread_t threads[num_threads];
int thread_args[num_threads];
sem_init(&sem, 3); // Initialize semaphore with count 2
// Create threads
for (int i = 0; i < num_threads; i++) {
thread_args[i] = i;
pthread_create(&threads[i], NULL, thread_function, &thread_args[i]);
}
// Wait for threads to finish
for (int i = 0; i < num_threads; i++) {
pthread_join(threads[i], NULL);
}
sem_destroy(&sem); // Clean up semaphore
return 0;
}
#include "semaphore.h"
void sem_init(semaphore *sem, int count) {
// TODO: implement this function
}
void sem_wait(semaphore *sem) {
// TODO: implement this function
}
void sem_post(semaphore *sem) {
// TODO: implement this function
}
void sem_destroy(semaphore *sem) {
// TODO: implement this function
}
#include <pthread.h>
typedef struct {
int count;
pthread_mutex_t mutex;
pthread_cond_t condition;
} semaphore;
void sem_init(semaphore *sem, int count);
void sem_wait(semaphore *sem);
void sem_post(semaphore *sem);
void sem_destroy(semaphore *sem);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment