thread-limit.c
/**
* thread-limit.c
*
* Demonstrates using a semaphore to limit the number of active threads in an
* application. This program will continue to launch threads and have them do
* "work" (sleeping) until terminated. Semaphores are often useful any time we
* wish to restrict the number of threads that can access a resource (or in this
* case, even exist!)
*
* Compile:
* gcc -pthread -g -Wall thread-limit.c -o thread-limit
*/
#include <pthread.h>
#include <semaphore.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>
sem_t thread_semaphore;
void *thread_routine(void *param)
{
/* In this example, we need to detach the thread because it is not being
* join()ed in main(). If we don't do this, the thread will not be freed
* automatically and we'll eventually run out of memory */
pthread_detach(pthread_self());
/* Get thread ID */
/* Note: we use a Linux-specific system call to do this. */
pid_t tid = syscall(__NR_gettid);
/* Sleep for a random amount of time */
int random = rand() % 5;
printf(" -> Thread %d sleeping for %ds\n", tid, random);
sleep(random);
/* Free up the resource */
sem_post(&thread_semaphore);
return 0;
}
int main(void)
{
int max_threads = 4;
sem_init(&thread_semaphore, 0, max_threads);
while (true) {
pthread_t thread;
/* Acquire the resource. If the semaphore count has hit 0, then we will
* block (wait) here. */
sem_wait(&thread_semaphore);
int ret = pthread_create(&thread, NULL, thread_routine, (void *) 0);
if (ret != 0) {
perror("pthread_create");
}
}
sem_destroy(&thread_semaphore);
return 0;
}