shared memory

Work in Progress

Summary

POSIX syscalls for shared memory

SyscallIncludeFunction
shmid = shmget(IPC_PRIVATE, size, shmflg)<sys/shm.h>creates a shared memory region
returns the id of the shared memory or -1 if error
shm = shmat(shmid, NULL, shmflg)<sys/shm.h>attach the shared memory to the current process
returns a pointer to the shared memory location or -1 if error
shmdt(shm)<sys/shm.h>detach the shared memory from the current process
returns 0 on success, -1 on error
shmctl(shmid, IPC_RMID, 0)<sys/shm.h>delete the shared memory region
returns 0 on success, -1 on error

Sharing memory

  • master
c
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main() {
	int shmid, i, *shm;
	
	shmid = shmget(IPC_PRIVATE, 40, IPC_CREAT | 0600);
	if (shmid == -1) {
		printf("Cannot create shared memory!\n");
		exit(1);
	} else
		printf("Shared Memory Id = %d\n", shmid);
	
	shm = (int*) shmat(shmid, NULL, 0);
	if (shm == (int*) -1){
		printf("Cannot attach shared memory!\n");
		exit(1);
	}
	
	shm[0] = 0;
	
	while(shm[0] == 0) {
		sleep(3);
	}
	
	for (i = 0; i < 3; i++) {
		printf("Read %d from shared memory.\n", shm[i+1]);
	}
	
	shmdt((char*) shm);
	shmctl(shmid, IPC_RMID, 0);
	return 0;
} 
  • slave
c
//similar header files
int main() {
	int shmid, i, input, *shm;
	printf("Shared memory id for attachment: ");
	scanf("%d", &shmid);
	shm = (int*)shmat(shmid, NULL, 0);
	if (shm == (int*)-1) {
		printf("Error: Cannot attach!\n");
	exit(1);
	}
	
	for (i = 0; i < 3; i++) {
		scanf("%d", &input);
		shm[i+1] = input;
	} 
	shm[0] = 1;
	
	shmdt((char*)shm);
	return 0;
} 

Concept

  • memory region created by a process storeed in the OS’s memory space
  • other processes can attach the memory space
  • pros:
    • efficient - only create and attach invole the OS
    • easy to use - shared memory behaves like normal memory
  • cons:

Application

Setup shared memory before fork

c
int i, shmid, n = 100, childPid, nChild = 1;
int *shm;

if (argc > 1)
		n = atoi(argv[1]);

if (argc > 2)
		nChild = atoi(argv[2]);

// create Shared Memory Region
// read, write, excute
// 1      1      0        = 6
// 1      0      0        = 4
shmid = shmget(IPC_PRIVATE, 1*sizeof(int), IPC_CREAT | 0600);
// 0 prefix denotes a octal number
if (shmid == -1) {
		printf("Cannot create shared memory!\n");
		exit(1);
}
else {
		printf("Shared Memory Id = %d\n", shmid);
}

// Attach the shared memory region to this process
shm = (int*)shmat(shmid, NULL, 0);
if (shm == (int*) -1) {
		printf("Cannot attach shared memory!\n");
		exit(1);
}
shm[0] = 0;
   // initialize shared memory to 0

for (i = 0;
i < nChild;
i++) {
		childPid = fork();
		if (childPid == 0)
				break;
}

// both parent and child increase the value in the shared memory n times
for (i = 0;
i < n;
i++)
		shm[0]++;

if (childPid != 0) {
		for (i = 0;
i < nChild;
i++) // wait for all child processes
				wait(NULL);
		printf("The value in the shared memory is: %d\n", shm[0]);
		// detach and destroy
		shmdt((char*)shm);
		shmctl(shmid, IPC_RMID, 0);
}