thread-limit.c

DownloadView Raw

/**
 * 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;
}