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); }
}