This program uses a custom semaphore to synchronize threads incrementing a shared counter. Each thread runs a function that waits for the semaphore (sem_wait
), increments the counter, and signals the semaphore (sem_post
). The semaphore ensures mutual exclusion, preventing race conditions. The main function initializes the semaphore, creates threads, waits for them to finish, and prints the final counter value.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
struct __sem_t
{
int value;
pthread_mutex_t mutex;
pthread_cond_t cond;
} typedef sem_t;
sem_t sem_lock;
volatile int counter = 0;
int loops = 100;
void sem_init(sem_t *s, int v)
{
s->value = v;
}
void sem_wait(sem_t *s)
{
pthread_mutex_lock(&s->mutex);
while (s->value <= 0)
pthread_cond_wait(&s->cond, &s->mutex);
s->value--;
pthread_mutex_unlock(&s->mutex);
}
void sem_post(sem_t *s)
{
pthread_mutex_lock(&s->mutex);
s->value++;
pthread_cond_signal(&s->cond);
pthread_mutex_unlock(&s->mutex);
}
void *func()
{
for (int i = 0; i < loops; i++)
{
sem_wait(&sem_lock);
counter++;
sem_post(&sem_lock);
}
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
fprintf(stderr, "usage: %s <value> <num_threads>\n", argv[0]);
exit(1);
}
pthread_mutex_init(&sem_lock.mutex, NULL);
pthread_cond_init(&sem_lock.cond, NULL);
int num_threads = atoi(argv[2]);
pthread_t t[num_threads];
loops = atoi(argv[1]);
sem_init(&sem_lock, 1);
for (int i = 0; i < num_threads; i++)
{
pthread_create(&t[i], NULL, func, NULL);
}
for (int i = 0; i < num_threads; i++)
{
pthread_join(t[i], NULL);
}
printf("%d\n", counter);
}
Usage:
gcc -pthread -o semaphore semaphore.c
./semaphore 100 2
Output:
200