XSI IPC

advertisement

XSI IPC

Message Queues

Semaphores

Shared Memory

XSI IPC

Each XSI IPC structure has two ways to identify it

An internal (within the Kernel) non negative integer identifier

An external key value of type key_t

We must specify a key when we create an XSI IPC structure. This is converted to an internal identifier by the Kernel

XSI IPC

No file system representation as with

FIFOs ipcs to list XSI IPCs ipcrm to remove a XSI IPC

Creating Keys

3 ways

Server creates XSI IPC structure with a key of

IPC_PRIVATE and stores the returned internal identifier in a file for the client to read

Client and Server agree ahead of time on the key.

Requires error handling in case the key is already in use

Client and Server agree on a pathname and project ID and use the ftok function

ftok

key_t ftok(const char *pathname, int proj_id);

pathname

must be the path to an existing file

proj_id

contains a value between 0 and

255 (only lower 8 bits of int are used)

Note that occasionally different pathnames with the same project id can return the same key!

Permissions Structure

Every XSI IPC structure has a permissions structure associated with it struct ipc_perm { key_t key; /* Key */ uid_t uid; /* Effective UID of owner */ gid_t gid; /* Effective GID of owner */ uid_t cuid; /* Effective UID of creator */ gid_t cgid; /* Effective GID of creator */ unsigned short mode; /* Permissions */ unsigned short seq; /* Sequence number */

};

Permissions Structure

All fields are initialized when the IPC structure is created

mode

is the same as for the open function but no execute permission uid, gid, and mode can be modified with msgctl, semctl or shmctl

Only the creator of the IPC or root can change these

Message Queues

Similar to FIFO. Allows two (or more) processes to exchange data

Not FIFO, messages may be retrieved out of order

Message queue remains until deleted or system rebooted

Message Queues

Message Queues are linked lists of messages in Kernel memory

Each message queue has its own identifier

Messages within queue can be of different types

Queue opened or created with msgget

New messages added with msgsnd

Messages de-queued with msgrcv

Message Queues

struct msqid_ds { struct ipc_perm msg_perm; /* Ownership and permissions */ time_t msg_stime; /* Time of last msgsnd() */ time_t msg_rtime; /* Time of last msgrcv() */ time_t msg_ctime; /* Time of last change */ msgqnum_t msg_qnum; /* Current number of messages in queue */ msglen_t msg_qbytes; /* Maximum number of bytes allowed in queue */ pid_t msg_lspid; /* PID of last msgsnd() */ pid_t msg_lrpid; /* PID of last msgrcv() */

};

Message Queues

Kernel defined limits

MSGMAX: Max size in bytes of a single message

MSGMNB: Max size in bytes of a single queue

MSGMNI: Max number of message queues system wide

MSGTQL: Max number of messages system wide

msgget

int msgget(key_t key, int msgflg);

Gets or creates a queue. is used to initialize the the permission structure

msgflg

param

mode

member of

Returns message queue ID if ok and -1 on error

msgsnd

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

msqid

internal ID of message queue

msgsz

size in bytes of the message

msgflg

OR of zero or more of: IPC_NOWAIT,

MSG_NOERROR

msgp

pointer to actual message

msgsnd

msgp

pointer to the actual message.

Must be of the form struct mymsg { long mytype; char mytext[512];

};

msgrcv

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

Retrieves a message from the queue

msgsz

is the size in bytes of the text portion of the structure pointed to by

msgp msgp

is a pointer to a structure that will hold the message retrieved from the queue

msgrcv

msgtyp

used to retrieve messages out of order

 msgtyp = 0 - retrieve the first message on the queue msgtyp > 0 - return the first message with a matching type msgtyp < 0 - return the first message on the queue with a type <= |msgtyp|

msgctl

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

Performs various operations on a message queue cmd

IPC_STAT - gets the msqid_ds structure

IPC_SET - sets the following fields of the msqid_ds structure: msg_perm.uid, msg_perm.gid, msg_perm.mode, msg_qbytes

IPC_RMID - removes the queue

Semaphores

Similar to a mutex with a built in counter

Provides controlled access to shared resources

Counter may be any positive integer

Binary semaphores – value of 0 or 1

Semaphores

To obtain access to a shared resource

Test the semaphore that controls the resource

If the value is positive, decrement the semaphore count by 1 and access the resource

Otherwise, (value is 0) sleep until another process releases the resource and increments the semaphore then repeat

Semaphores

Data structure for semaphore set struct semid_ds { struct ipc_perm sem_perm; time_t sem_otime; /* Last semop time */ time_t sem_ctime; /* Last change time */ unsigned short sem_nsems; /* # in set */

};

Semaphores

Anonymous data structure for a single semaphore struct { unsigned short semval; /* value always >= 0 */ pid_t sempid; /* pid for last operation */ unsigned short semncnt; unsigned short semzcnt;

};

semget

Create or access a semaphore set int semget(key_t key, int nsems, int semflg);

 nsems number of semaphores in this set. nsems > 0 when server is creating set, and

== 0 when client is accessing existing set semflg the mode member of the permissions struct is initialized with the corresponding permission bits of semflg

semop

int semop(int semid, struct sembuf *sops, unsigned nsops); struct sembuf { unsigned short sem_num; /* semaphore number */ short sem_op; /* semaphore operation */ short sem_flg; /* operation flags */

};

 sops is a pointer to an array of sembuf structs nsops is the number of elements in the array

All the operations are performed atomically

semop

 sem_op

> 0 - process releasing resources. Value of sem_op added to the semaphores current value

< 0 - process needs resources. If semaphores value is >= sem_op then sem_op is subtracted from it and the process can use the resource.

Otherwise, semncnt incremented and process goes to sleep

== 0 - process wants to wait until the semaphores value is zero. semzcnt incremented and process is put to sleep

semctl

int semctl(int semid, int semnum, int cmd, union semun arg);

 semid semaphore set ID semnum index of a particular semaphore in the set cmd operation to be performed. IPC_RMID to delete semaphore. See page 530 for full list arg optional 4 th argument. Not required for all commands. Note that this is NOT a pointer so we can’t pass in NULL

Shared Memory

Allows unrelated process to share an area of memory

Faster because no copying needed

Must be careful to control access (often through the use of semaphores)

Shared Memory

struct shmid_ds { struct ipc_perm shm_perm; /* Ownership and permissions */ size_t shm_segsz; /* Size of segment (bytes) */ time_t shm_atime; /* Last attach time */ time_t shm_dtime; /* Last detach time */ time_t shm_ctime; /* Last change time */ pid_t shm_cpid; /* PID of creator */ pid_t shm_lpid; /* PID of last shmat()/shmdt() */ shmatt_t shm_nattch; /* No. of current attaches */

...

};

shmget

int shmget(key_t key, size_t size, int shmflg);

 size number of bytes – specified by the server when creating the shared memory area. Client passes zero for this parameter shmflg – mode member of permissions struct set with the corresponding bits

shmat

void *shmat(int shmid, const void *shmaddr, int shmflg);

Attaches a shared memory segment to the current process

 shmid the ID of the shared memory segment shmaddr if zero is passed in (recommended)

Kernel will attach at first available location shmflg SHM_RND – rounds to next page boundary, SHM_RDONLY, 0 (attached read/write)

shmdt

int shmdt(const void *shmaddr);

Detaches a shared memory segment

shmaddr

is the address of the memory segment to detach

Returns 0 on success or -1 on error

Download