300 likes | 371 Views
Learn about XSI IPCs with keys for identification, permissions structure, message queues for data exchange, and semaphores for resource access control in this comprehensive guide.
E N D
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. msgflg param is used to initialize the mode member of the permission structure • 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 4th 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