I am trying to write a semaphore using signals. code in main the checks that it works, it suppose to print (something like):
Thread 2 trying to enter critical section…
Thread 2 entered critical section.
Thread 1 trying to enter critical section…
Thread 2 leaving critical section.
Thread 1 entered critical section.
Thread 1 leaving critical section.
where every thread enters and leaves.
But it prints:
Thread 2 trying to enter critical section…
Thread 2 entered critical section.
Thread 1 trying to enter critical section…
Thread 2 leaving critical section.
and doesn’t print that the other thread is also entering and leaving the critical section, also it doesn’t terminate. My guess is that I don’t understand how the sigsusppend() is working. Thank you in advance.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
// Global semaphore
volatile sig_atomic_t semaphore = 1;
// Signal handling function
void signal_handler(int sig) {
semaphore = 1; // Release the semaphore
}
// Initialize the semaphore
void sem_init() {
struct sigaction sa;
sa.sa_handler = signal_handler;
sa.sa_flags = 0; // No flags
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, NULL);
// Block SIGUSR1 to prevent premature handling
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &set, NULL);
}
// Wait (down operation) on the semaphore
void sem_down() {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
while (!semaphore) {
sigsuspend(&set); // Replace pause with sigsuspend for targeted waiting
}
semaphore = 0; // Take the semaphore
}
// Signal (up operation) on the semaphore
void sem_up() {
semaphore = 1;
kill(getpid(), SIGUSR1); // Send signal to release semaphore
}
// A simple thread function that uses the semaphore
void* thread_func(void* arg) {
printf("Thread %ld trying to enter critical section...n", (long)arg);
sem_down();
printf("Thread %ld entered critical section.n", (long)arg);
sleep(2); // Simulate critical section work
sem_up();
printf("Thread %ld leaving critical section.n", (long)arg);
return NULL;
}
// Main function to demonstrate semaphore usage
int main() {
sem_init();
pthread_t t1, t2;
pthread_create(&t1, NULL, thread_func, (void*)1);
pthread_create(&t2, NULL, thread_func, (void*)2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}