C++ | Semaphore | Embedded System | OS
1270

Semaphore Example

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>  //Header file for sleep(). man 3 sleep for details.
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

using namespace std;

sem_t mutex;
int sem_val = 1; /* Semaphore value 1 */
int sem_type = 1; /* 0 For threads, 1 for Process */

int counter = 0;
void *thread_handler(void *vargp)
{
    sem_wait(&mutex);
    counter++;
    cout << "Job" << *(int *)vargp << " started, counter=" << counter << endl;
	/* Run below program with/without sleep(1),
	 * when sleep is included, we need to have mutex
	 */
    sleep(1);
    cout << "Job" << *(int *)vargp << " finished, counter=" << counter << endl;
    sem_post(&mutex);
    return NULL;
}

int main()
{
    pthread_t thread_id[30];
    int thread_arg[30];

    /* Non recursive mutex */
    if(sem_init(&mutex, sem_type, sem_val)) {
    	cout << "sem not initialized successfully" << endl;
    }


    printf("Before Thread\r\n");
    for(int i = 0; i < 5; i++) {
    	thread_arg[i] = i;
    	pthread_create(&thread_id[i], NULL, thread_handler, (void *)&thread_arg[i]);
    }

    for(int i = 0; i < 5; i++) {
        pthread_join(thread_id[i], NULL);
    }

    sem_destroy(&mutex);

    return 0;
}

Implement your own Semaphore

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <condition_variable>

using namespace std;

#define THREAD_CNT 30

class semaphore {
private:
   int m_value;                    // Value of semaphore.
   pthread_mutex_t sync_mutex;               // Controls access.
   pthread_cond_t condition;; // Controls waiting and restart
public:
    semaphore(int init): m_value(init) {
       pthread_mutex_init(&sync_mutex, NULL);
       pthread_cond_init(&condition, NULL);
    }
    ~semaphore(){
       pthread_mutex_destroy(&sync_mutex);
       pthread_cond_destroy(&condition);
    }
    void down() {
        pthread_mutex_lock(&sync_mutex);
       // Check the mutex value, and wait if need be.
       if(--m_value < 0) {
           // Make us wait.  When we wait, the mutex is unlocked until the
           // wait ends.
           pthread_cond_wait(&condition, &sync_mutex);
       }
    }
    void up() {
       // Start a waiting thread if required.
       if(++m_value <= 0) {
           pthread_cond_signal(&condition);
       }
       pthread_mutex_unlock(&sync_mutex);
    }
};
semaphore sem(1);

int shared_resource = 0;
void *thread_handler(void *vargp)
{
	sem.down();

    shared_resource++;
    std::cout << "Job" << *(int *)vargp << " started, shared_resource=" << shared_resource << endl << std::flush;
    sleep(1);
    std::cout << "Job" << *(int *)vargp << " finished, shared_resource=" << shared_resource << endl << std::flush;

    sem.up();
    return NULL;
}

int main()
{
    pthread_t thread_id[THREAD_CNT];
    int thread_arg[THREAD_CNT];

    for(int i = 0; i < THREAD_CNT; i++) {
    	thread_arg[i] = i;
    	pthread_create(&thread_id[i], NULL, thread_handler, (void *)&thread_arg[i]);
    }

    for(int i = 0; i < THREAD_CNT; i++) {
        pthread_join(thread_id[i], NULL);
    }

    return 0;
}
Comments (0)