Semaphores allow processes to avoid clashes when accessing shared resources, for instance shared memory.

Generating A Random Key

Humans aren't very good at picking random values so use a site like this one: www.random.org/integers/

It won't do a 32bit 1 to 2147483647, but it will do 1 to 1000000000

Simple Example Of Creating & Using A Semaphore

Header Files Needed

#include <sys/sem.h>		//Used for semaphores

 

Defining The Semaphore Your Header File

//----- SEMAPHORE -----
//On linux systems this union is probably already defined in the included sys/sem.h, but if not use this default basic definition:
union semun {
	int val;
	struct semid_ds *buf;
	unsigned short *array;
};

//FUNCTIONS:
static int semaphore1_get_access(void);
static int semaphore1_release_access(void);
//VARIABLES:
static int semaphore1_id;
The Functions


//***********************************************************
//***********************************************************
//********** WAIT IF NECESSARY THEN LOCK SEMAPHORE **********
//***********************************************************
//***********************************************************
//Wait if necessary and then change the semaphore by –1. This is the "wait" operation
static int semaphore1_get_access(void)
{
	struct sembuf sem_b;
	sem_b.sem_num = 0;
	sem_b.sem_op = -1; /* P() */
	sem_b.sem_flg = SEM_UNDO;
	if (semop(semaphore1_id, &sem_b, 1) == -1)		//Wait until free
	{
		fprintf(stderr, "semaphore1_get_access failed\n");
		return(0);
	}
	return(1);
}

//***************************************
//***************************************
//********** RELEASE SEMAPHORE **********
//***************************************
//***************************************
//Setting the semaphore back to available.  This is the "release" operation.

static int semaphore1_release_access(void)
{
	struct sembuf sem_b;
	sem_b.sem_num = 0;
	sem_b.sem_op = 1; /* V() */
	sem_b.sem_flg = SEM_UNDO;
	if (semop(semaphore1_id, &sem_b, 1) == -1)
	{
		fprintf(stderr, "semaphore1_release_access failed\n");
		return(0);
	}
	return(1);
}
Create The Semaphore

	//----------------------------
	//----- CREATE SEMAPHORE -----
	//----------------------------
	printf("Creating semaphore...\n");
	semaphore1_id = semget((key_t)12345, 1, 0666 | IPC_CREAT);		//<<<<< SET THE SEMPAHORE KEY   (Semaphore key, number of semaphores required, flags)
	//	Semaphore key
	//		Unique non zero integer (usually 32 bit).  Needs to avoid clashing with another other processes semaphores (you just have to pick a random value and hope - ftok() can help with this but it still doesn't guarantee to avoid colision)

	//Initialize the semaphore using the SETVAL command in a semctl call (required before it can be used)
	union semun sem_union_init;
	sem_union_init.val = 1;
	if (semctl(semaphore1_id, 0, SETVAL, sem_union_init) == -1)
	{
		fprintf(stderr, "Creating semaphore failed to initialize\n");
		exit(EXIT_FAILURE);
	}
Using The Semaphore

	//----- SEMAPHORE GET ACCESS -----
	if (!semaphore1_get_access())
		exit(EXIT_FAILURE);

	//... do the interlocked action ...

	//----- SEMAPHORE RELEASE ACCESS -----
	if (!semaphore1_release_access())
		exit(EXIT_FAILURE);
Deleting The Semaphore

	//----------------------------
	//----- DELETE SEMAPHORE -----
	//----------------------------
	//It's important not to unintentionally leave semaphores existing after program execution. It also may cause problems next time you run the program.
	union semun sem_union_delete;
	if (semctl(semaphore1_id, 0, IPC_RMID, sem_union_delete) == -1)
		fprintf(stderr, "Failed to delete semaphore\n");