Disclaimer: It is possible that this description contains errors in prototypes. See the man pages for any discrepancies or questions.
For shared memory and semaphores, you must include the following libraries: <sys/types.h>, <sys/ipc.h>,<sys/errno.h>,<stdio.h>,
<sys/shm.h>, and <sys/sem.h>.
System calls usually return -1 if the call failed and set the global
variable errno to the error returned by the kernel. The values that errno
can take along with a brief description of each error can be found in the
header file <sys/errno.h>.You must test the return value from each system call for success.
IPC objects are message queues, semaphores, and shared memory segments. Shared memory and semaphores are described on this page. Shared memory and semaphores are requested from the operating system.
To refer to the IPC structure in the kernel, a nonnegative integer called an identifier is used. An IPC key identifies an IPC object to be used for sharing among multiple processes. The assignment is permanent. You must return them explicitly.
For every semaphore required by your program, you must obtain the semaphore from the system and give the semaphore an initial value.
The semget function either creates a new semaphore or returns the identifier
of an existing semaphore. In your program, you will only be using semget
to create a new semaphore for each semaphore required.
int semget(key_t key, int nsems, int semflg);
In your program :
#define SEMPERM 0600 /* permission for semaphore */
int semid;
semid = semget(IPC_PRIVATE,1,SEMPERM|IPC_CREAT|IPC_EXCL);
By specifying IPC_PRIVATE for the key, the operating system will create a brand new IPC structure. This is used in a parent-child relationship. The parent creates a new IPC structure by specifying IPC_PRIVATE and the resulting identifier is then available to the child after the fork.
The low-order 9 bits of the semflag are permissions: rwx for owner,
group, and everyone else. We are setting the permissions to read and write
for the owner. IPC_CREAT and IPC_EXCL flags are required to ensure that
a new IPC structure will be created (making sure we don't reference an
existing structure with the same identifier).
You must set each semaphore to an initial value. To do this, you will
need to create a union as described below and call the procedure semctl.
union {
int val;
struct semid_ds *buffer;
ushort *array;
}semnum;
semnum.val = your initialization value;
semctl(semid,0,SETVAL, semnum);
At the completion of the processing the program should return the semaphores. This is very important as the system has a fixed number of semaphores and if you do not return them, others cannot use them and the system will eventually run out. The semctl procedure is also used to return the semaphore to the system:
semctl(semid,0,IPC_RMID,NULL);
To perform the wait on the semaphore, you should use the following procedure:
void p(int semid)
{
struct sembuf p_buf;
p_buf.sem_num = 0;
p_buf.sem_op = -1;
p_buf.sem_flg = 0;
if (semop(semid,&p_buf,1) < 0)
{
printf("fatal p error on semaphore %i",semid);
}
}
sembuf is defined in sem.h.
To Signal the semaphore, use the following procedure:
void v(int semid)
{
struct sembuf v_buf;
v_buf.sem_num = 0;
v_buf.sem_op = 1;
v_buf.sem_flg = 0;
if(semop(semid,&v_buf, 1) < 0)
{
printf("fatal v error on semaphore %i",semid);
}
}
I would suggest modifying p and v to return the value returned by semop
so the caller knows whether p and v were successful.
See the man pages for more information
To obtain a segment of memory that can be used for sharing:
#define SHMPERM 0600
int segid;
segid= shmget (IPC_PRIVATE,size,IPC_CREAT|IPC_EXCL|SHMPERM);
See above for an explanation of IPC_Private, IPC_CREAT, IPC_EXCL, and SHMPERM.
You should define size the size of the block required.
Before the shared memory can be used, it must be attached to all of the
processes that are to use it. It can be attached before
or after the fork.
char * buf;
buf = (char *)shmat (segid, (char *)0,0);
As with semaphores, the shared segment must be returned prior to termination:
shmctl(segid,IPC_RMID,NULL);
Semaphores and shared segments are "permanent." As you try to
get your program to run, you will probably get some and your program will
crash before it returns them. Use the system utility programs ipcs and
ipcrm to clean up after yourself. If you do not, the system will run out
of semaphores and/or shared segments and no one else will be able to get
any (including you). Needless to say, your classmates (and others) will
not be happy with you.
ipcs: report interprocess communication facilities status
ipcrm: removes a message queue, semaphore set, or shared memory ID.
You can also execute:
cs326clean
It is a script written by a former CS326 student.
Above, you are given the details of the system calls you to use shared memory and shared semaphores. You can use man followed by procedure name on the Unix command line to obtain additional information regarding any of the system calls.
Last modified 1:28 PM 11/07/2024
This page is copyright protected © by Barbara Bracken