So I’m making a Load.c file, that basically will load a bunch of “students” into shared memory.
The students are stored in a struct that looks like this:
struct StudentInfo{
char fName[20];
char lName[20];
char telNumber[15];
char whoModified[10];
};
Anyway, I need to load this in shared memory. We were given some sample code and we are reading the code from a data file that will look like this:
John Blakeman
111223333
560 Southbrook Dr. Lexington, KY 40522
8591112222
Paul S Blair
111223344
3197 Trinity Rd. Lexington, KY 40533
etc....
Here’s my idea for the code: (header.h just has struct info/ and semaphore count….I’m unsure of what it needs to be, right now it’s labeled as 5)
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include "header.h"
main()
{
int i,id;
struct StudentInfo *infoptr;
int sema_set;
id = shmget(KEY, SEGSIZE,IPC_CREAT|0666); /* get shared memory to store data */
if (id < 0){
perror("create: shmget failed");
exit(1);
}
infoptr=(struct StudentInfo *)shmat(id,0,0); /* attach the shared memory segment to the process's address space */
if(infoptr <= (struct StudentInfo *) (0)) {
perror("create: semget failed");
exit(2);
}
/* store data in shared memory segment */
//here's where I need help
That’s about as far as I got. now I know I can store data using strcpy(infoptr->fName,”Joe”); (for example)
but I need to read an X number of names? How would I go about storing them? Using some sort of push/pop vector of structs? how would it look like?
And do I adjust semaphores based on how many “entries” there are I assume? I’m a little bit confused how to adjust my number of semaphores.
Oh BTW here’s my header file just in case (SSN’s are fake obviously)
/* header.h */
#define KEY ((key_t)(10101)) /* Change to Last 5 digits of SSN */
#define SEGSIZE sizeof(struct StudentInfo)
#define NUM_SEMAPHS 5
#define SEMA_KEY ((key_t) (1010)) /* Last 4 digits of SSN */
struct StudentInfo{
char fName[20];
char lName[20];
char telNumber[15];
char whoModified[10];
};
void Wait(int semaph, int n);
void Signal(int semaph, int n);
int GetSemaphs(key_t k, int n);
Uhm… I’m not sure here, but this is what I understood:
You’re loading
struct StudentInfoblocks into a shared memory space, and you want to be able to access it from other processes?First, consider that your structure is fixed-size. If you want to read 10 names, you need to get
sizeof(struct StudentInfo) * 10bytes, if you want 400, make that* 400— so you don’t need to push and pop your students from any kind of queue, since you can just use math to calculate from where and up to where you need to read. Getting students 10 to 20 is just reading the shared memory space fromsizeof(struct StudentInfo) * 10tosizeof(struct StudentInfo) * 10As for mutual exclusion (if you’re going to have multiple readers or writers, which I assume is what you wanted the semaphores for), I do not recommend semaphores. They are adequate for simpler kinds of exclusion, like “don’t use this function if I’m using it”, but not for locking large sets of data.
I’d use
file locking. In Unix, you can usefile locking primitivesto create advisory locks over specific bytes in a file, even if the file is 0-bytes-long. What does this mean?Advisory means you don’t enforce them, other processes must respect them willingly. 0-byte-long means you can open a file that doesn’t exist, and lock portions of it corresponding to your student structure positions in shared memory. You don’t need the file to actually have data, you can use it to represent your shared memory database without writing anything to it.
What’s the advantage of this over semaphores? You have fine-grained control of your locks with a single file descriptor!
Wheh, that got long. Hope I helped.