0% found this document useful (0 votes)
3 views4 pages

Semaphore and Shared Memory Example

The document contains code for semaphore operations and a producer-consumer model using shared memory in C. It includes functions for creating, initializing, and manipulating semaphores, as well as managing shared memory segments. The producer and consumer processes utilize these semaphores to synchronize access to a circular buffer.

Uploaded by

hassani.chaima18
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views4 pages

Semaphore and Shared Memory Example

The document contains code for semaphore operations and a producer-consumer model using shared memory in C. It includes functions for creating, initializing, and manipulating semaphores, as well as managing shared memory segments. The producer and consumer processes utilize these semaphores to synchronize access to a circular buffer.

Uploaded by

hassani.chaima18
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Semaphore.

h }

#include <stdio.h> // V operation (signal/increment) on semaphore


#include <sys/ipc.h> void v(int semid, int semnum) {
#include <sys/sem.h> struct sembuf sb;
sb.sem_num = semnum; // Semaphore number in group
// Create or get a group of nsems semaphores with given key sb.sem_op = 1; // Increment operation
// Returns semaphore group ID sb.sem_flg = SEM_UNDO; // Auto cleanup if process dies
int create_sm(int nsems, key_t key) { if (semop(semid, &sb, 1) < 0) {
int semid = semget(key, nsems, IPC_CREAT | IPC_EXCL | 0666); perror("V semop failed\n");
if (semid < 0) { } else {
// If creation fails, get existing semaphore group printf("V semop executed successfully\n");
semid = semget(key, nsems, 0); }
printf("Semaphor group already exists with id (%d)\n", semid); }
} else
printf("New semaphore group created with id (%d)\n", semid); // Z operation (wait for zero) on semaphore
return semid; void z(int semid, int semnum) {
} struct sembuf sb;
sb.sem_num = semnum; // Semaphore number in group
// Initialize a semaphore in group semid with given value sb.sem_op = 0; // Wait for zero operation
void init_sm(int semid, int semnum, int val) { sb.sem_flg = 0; // No special flags needed
if (semctl(semid, semnum, SETVAL, val) < 0) { if (semop(semid, &sb, 1) < 0) {
perror("Init semctl failed\n"); perror("Z semop failed\n");
} else { } else {
printf("Init semctl successful\n"); printf("Z semop executed successfully\n");
} }
} }

// P operation (wait/decrement) on semaphore // Remove/destroy a semaphore group


void p(int semid, int semnum) { void sem_destroy(int semid) {
struct sembuf sb; if (semctl(semid, 0, IPC_RMID) < 0) {
sb.sem_num = semnum; // Semaphore number in group perror("semctl IPC_RMID failed\n");
sb.sem_op = -1; // Decrement operation } else {
sb.sem_flg = SEM_UNDO; // Auto cleanup if process dies printf("Semaphore set removed successfully.\n");
if (semop(semid, &sb, 1) < 0) { }
perror("P semop failed\n"); }
} else {
printf("P semop executed successfully\n");
}
Create.c: }

#include "semaphore.h" // Attach shared memory segment to process address space


#include <stdio.h> shared_data *sd = shmat(shmid, NULL, 0);
#include <stdlib.h> if (sd == (void *)-1) {
#include <sys/shm.h> perror("Échec de shmat");
#include <sys/types.h> exit(EXIT_FAILURE);
#include <sys/wait.h> }
#include <unistd.h>
// Initialize shared memory indices to 0
// Define shared memory structure for producer-consumer sd->producer_index = 0;
typedef struct shared_data { sd->consumer_index = 0;
int producer_index; // Index where producer will write printf("Indexes initialisés (Producteur : %d, Consommateur : %d)\n",
int consumer_index; // Index where consumer will read sd->producer_index, sd->consumer_index);
int buffer[10]; // Circular buffer of size 10
} shared_data; // Create and initialize semaphores:
// semid[0]: counts empty slots (initial=10)
int main() { // semid[1]: counts full slots (initial=0)
// Generate unique key for shared memory using current // semid[2]: mutex for producers (initial=1)
directory // semid[3]: mutex for consumers (initial=1)
key_t key = ftok(".", 'b');

// Create shared memory segment int semid = create_sm(4, key);


// IPC_CREAT: create if doesn't exist init_sm(semid, 0, 10); // Empty slots counter
// IPC_EXCL: fail if already exists init_sm(semid, 1, 0); // Full slots counter
// 0666: read/write permissions for all init_sm(semid, 2, 1); // Producer mutex
int shmid = shmget(key, sizeof(shared_data), IPC_CREAT | init_sm(semid, 3, 1); // Consumer mutex
IPC_EXCL | 0666);
return 0;
// Handle shared memory creation/access }
if (shmid < 0) {
// If creation failed, try to get existing segment
shmid = shmget(key, sizeof(shared_data), 0);
printf("Le segment de mémoire partagée existe déjà avec
l'ID : %d\n",
shmid);
} else {
printf("Nouveau segment de mémoire partagée créé avec
l'ID : %d\n", shmid);
Produce.c: // Get access to semaphores
int semid = create_sm(4, key);
int value;
#include "semaphore.h"
#include <stdlib.h>
// Infinite production loop
#include <sys/shm.h>
while (1) {
#include <unistd.h>
// Skip if current buffer position is not empty
if (sd->buffer[sd->producer_index] != 0) {
// Define shared memory structure for producer-consumer
continue;
typedef struct shared_data {
}
int producer_index; // Write position in buffer
int consumer_index; // Read position in buffer
// Generate random value between 0-9
int buffer[10]; // Circular buffer
value = rand() % 10;
} shared_data;
printf("Valeur produite : %d\n", value);
int main() {
// Semaphore operations for synchronization
// Generate unique key for shared memory
p(semid, 0); // Wait for empty slot
key_t key = ftok(".", 'b');
p(semid, 2); // Get producer mutex
// Try to create shared memory segment
// Write to buffer and update index
int shmid = shmget(key, sizeof(shared_data), IPC_CREAT |
sd->buffer[sd->producer_index] = value;
IPC_EXCL | 0666);
sd->producer_index = (sd->producer_index + 1) % 10; // Circular
increment
if (shmid < 0) { // Segment already exists
shmid = shmget(key, sizeof(shared_data), 0);
v(semid, 2); // Release producer mutex
printf("Le segment de mémoire partagée existe déjà avec
v(semid, 1); // Signal one slot is full
l'ID : %d\n",
shmid);
// Display current buffer state
} else {
printf("Buffer = [%d, %d, %d, %d, %d, %d, %d, %d, %d, %d]\n",
printf("Nouveau segment de mémoire partagée créé avec
sd->buffer[0],
l'ID : %d\n", shmid);
sd->buffer[1], sd->buffer[2], sd->buffer[3], sd->buffer[4],
}
sd->buffer[5], sd->buffer[6], sd->buffer[7], sd->buffer[8],
sd->buffer[9]);
// Attach shared memory to process address space
shared_data *sd = shmat(shmid, NULL, 0);
// Wait 5 seconds before next production
if (sd == (void *)-1) {
sleep(5);
perror("Échec de shmat");
}
exit(EXIT_FAILURE);
return 0;
}
}
Consumer.c: // Get access to semaphores
int semid = create_sm(4, key);
#include "semaphore.h" int value;
#include <stdlib.h>
#include <sys/shm.h> // Infinite consumption loop
#include <unistd.h> while (1) {
// Skip if current buffer position is empty
// Define shared memory structure (same as producer and create) if (sd->buffer[sd->consumer_index] == 0) {
typedef struct shared_data { continue;
int producer_index; // Producer's write position }
int consumer_index; // Consumer's read position
int buffer[10]; // Circular buffer // Semaphore operations for synchronization
} shared_data; p(semid, 1); // Wait for full slot
p(semid, 3); // Get consumer mutex
int main() {
// Generate unique key for shared memory // Read from buffer and mark slot as empty
key_t key = ftok(".", 'b'); value = sd->buffer[sd->consumer_index];
sd->buffer[sd->consumer_index] = 0;
// Try to create/get shared memory segment sd->consumer_index = (sd->consumer_index + 1) % 10; // Circular
int shmid = shmget(key, sizeof(shared_data), IPC_CREAT | increment
IPC_EXCL | 0666);
v(semid, 3); // Release consumer mutex
if (shmid < 0) { // Segment exists v(semid, 0); // Signal one slot is empty
shmid = shmget(key, sizeof(shared_data), 0);
printf("Le segment de mémoire partagée existe déjà avec // Display consumed value and buffer state
l'ID : %d\n", printf("Consommation de la valeur : %d, à l'index %d\n", value,
shmid); sd->consumer_index);
} else { printf("Tampon = [%d, %d, %d, %d, %d, %d, %d, %d, %d, %d]\n",
printf("Nouveau segment de mémoire partagée créé avec sd->buffer[0], sd->buffer[1], sd->buffer[2], sd->buffer[3],
l'ID : %d\n", shmid); sd->buffer[4], sd->buffer[5], sd->buffer[6], sd->buffer[7],
} sd->buffer[8], sd->buffer[9]);

// Attach shared memory to process address space // Wait 5 seconds before next consumption
shared_data *sd = shmat(shmid, NULL, 0); sleep(5);
if (sd == (void *)-1) { }
perror("Échec de shmat"); return 0;
exit(EXIT_FAILURE); }
}

You might also like