IPC_CREAT, if the key is already
associated with an instance, its ID is returned, otherwise
a new instance is created and its ID returned.
IPC_EXCL flag is also specified (or'ed
with IPC_CREAT), an error is returned if the
key is already associated with an instance.
IPC_PRIVATE can be used.
No user key value is used, so the ID must be maintained
by the calling program.
IPC_RMID - remove identifier
IPC_SET - set options
IPC_STAT - get options
sys/ipc.h
struct ipc_perm {
ushort uid; /* owner's user id */
ushort gid; /* owner's group id */
ushort cuid; /* creator's user id */
ushort cgid; /* creator's group id */
ushort mode; /* access modes */
ushort seq; /* slot usage sequence number */
key_t key; /* key */
};
sys/ipc.h is required for each
facility, as well as an include file for the facility.
key_t), and may
be attached to by processes.
int shmget(key_t key,int size,int flags)
Returns the ID of a shared segment of size bytes, or -1 on
error. The flags are as described above.
void *shmat(int segment_ID,char *address,int flags)
Returns a pointer to the piece of shared memory associated with
the ID.
int shmdt(char *shared_memory)
Detaches the shared memory, returning 0 on success, -1 on error.
int shmctl(int segment_ID,int command,struct shmid_ds *status_buffer)
Used to get or set shared memory status, based on the commands
described above.
The status buffer is defined as:
struct shmid_ds {
struct ipc_perm shm_perm;
/* operation permission struct */
int shm_segsz; /* segment size */
ushort shm_segid; /* segment identifier */
ushort shm_lpid; /* pid of last shmop */
ushort shm_cpid; /* pid of creator */
ushort shm_nattch; /* current # attached */
ushort shm_cnattch; /* in memory # attached */
ushort shm_lcnt;
/* # processes locked out of this shm */
time_t shm_atime; /* last shmat time */
time_t shm_dtime; /* last shmdt time */
time_t shm_ctime; /* last change time */
struct segoffs *shm_segoffs;
/* segment offsets entry */
};
sys/shm.h is required.
key_t),
and each message on a queue has a message type (long).
long, being the type of the message.
int msgget(key_t key,int flags)
Returns a queue ID or -1 on error. The flags are as described
above.
int msgsnd(int queue_ID,struct msgbuf *buffer,int size,int flags)
size is the size of the message, less the
size of the message type field.
IPC_NOWAIT, which
causes an error return if the queue is full, otherwise the
process suspends until the queue empties sufficiently.
int msgrcv(int queue_ID,struct msgbuf *buffer,int max_size,long message_type,int flags)
MSG_NOERROR, in which case
the message is truncated.
IPC_NOWAIT flag is or'ed in, then
msgrcv returns immediately, even if there is no
appropriate message.
int msgctl(int queue_ID,int command,struct msqid_ds *status_buffer)
struct msqid_ds {
struct ipc_perm msg_perm; /* operation permission struct */
struct msg *msg_first; /* ptr to first message on q */
struct msg *msg_last; /* ptr to last message on q */
ushort msg_cbytes; /* current # bytes on q */
ushort msg_qnum; /* # of messages on q */
ushort msg_qbytes; /* max # of bytes on q */
ushort msg_lspid; /* pid of last msgsnd */
ushort msg_lrpid; /* pid of last msgrcv */
time_t msg_stime; /* last msgsnd time */
time_t msg_rtime; /* last msgrcv time */
time_t msg_ctime; /* last change time */
}
sys/msg.h is required.
int semget(key_t key,int number_of_semaphores,int flags)
Returns the ID of a set of semaphores, or -1 on error.
Flags as above.
int semop(int semaphore_ID,struct sembuf (*operations)[],int number_of_operations)
Simulateously operates on the semaphores identified.
operations points to an array of structures,
each of which is an operation on a semaphore in the set,
defined by:
struct sembuf {
ushort sem_num; /* semaphore # in set */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};
The amount by which the semaphore is changed is given in
sem_op.
SEM_UNDO - the effects of the process
on the semaphore set are undone when the process exits.
This is useful for ensuring a process does not exit whilst
holding resources.
IPC_NOWAIT - ensures the call returns
immediately, even if a semaphore cannot be decremented.
SEM_ORDER - perform ops non-atomically
SEM_ERR - set if error encountered
int semctl(int semaphore_ID,int semaphore_number,int command,union semnum argument)
GETNCNT - processes waiting for +ve value*/
GETPID - PID of last accessing process */
GETVAL - get semaphore value */
GETALL - get all semaphore values */
GETZCNT - processes waiting for 0 value*/
SETVAL - set semaphore value */
SETALL - set all semaphore values */
struct semid_ds {
struct ipc_perm sem_perm; /* permission struct */
struct sem *sem_base; /* ptr to first semaphore */
ushort sem_nsems; /* # of semaphores in set */
ushort semlcnt; /* # processes waiting on sem. */
time_t sem_otime; /* last semop time */
time_t sem_ctime; /* last change time */
};
SETVAL)
it's an integer.
SETALL)
it's an array of short.
sys/sem.h is required.
#include <stdio.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int main(void) {
int SemID;
struct sembuf SemOps[2];
SemID = semget((key_t) 1027,2,IPC_CREAT|S_IRUSR|S_IWUSR);
semctl(SemID,0,SETVAL,1);
semctl(SemID,1,SETVAL,0);
if (fork() == 0) {
SemOps[0].sem_num = 0;
SemOps[0].sem_op = -1;
SemOps[0].sem_flg = SEM_UNDO;
SemOps[1].sem_num = 1;
SemOps[1].sem_op = -1;
SemOps[1].sem_flg = SEM_UNDO;
semop(SemID,SemOps,2);
} else {
SemOps[0].sem_num = 1;
SemOps[0].sem_op = 1;
SemOps[0].sem_flg = SEM_UNDO;
semop(SemID,SemOps,1);
}
return(0);
}