410 likes | 433 Views
Learn about Unix IPC methods - Message Passing, Synchronization, Shared Memory, Remote Procedure Calls - SYSV and Posix, and how to implement them effectively.
E N D
Unix Inter-Process Communication Message Passing Synchronization Shared Memory Remote Procedure Calls
SYSV and Posix • SYSV • Designed by Bell Labs in the 1980s • Generally supported • Complicated and difficult to use • Posix • Developed as a realtime standard in the 1990s • Less generally supported • Simpler to use
Posix IPC • Message Queues • Semaphores • Shared Memory
Posix IPC Names • Name rules • must conform to existing rules for pathnames • at most PATH_MAX bytes • terminate with a NULL byte • Begin with `/’ • => all uses reference same entity • otherwise, effect is implementation dependent • Additional `/’s • interpretation is implementation defined
Solaris 2.6 Posix Name Conventions • Requires initial slash • Forbids additional slashes • Named entities are created in /tmp • Use #define to define names to make it easy to change for different operating systems.
Digital Unix Posix Name Conventions • Creates the specified pathname in the file system • Owner must have rights to create name • /bozo is generally invalid • created in root filesystem • Names generally have several slashes.
Posix Message Queues • Header • <mqueue.h> • Functions to create, open, or delete • mq_open() mq_close() mq_unlink() • Functions for control operations • mq_getattr() mq_setattr() • Functions for IPC operations • mq_send() mq_receive() mq_notify()
Posix Semaphores • Header • <semaphore.h> • Functions to create, open, or delete • sem_open() sem_close() sem_unlink() sem_init() sem_destroy() • Functions for IPC operations • sem_wait() sem_trywait() sem_post() sem_getvalue()
Posix Shared Memory • Header • <sys/mman.h> • Functions to create, open, or delete • shm_open() shm_unlink() • Functions for control operations • ftruncate() fstat() • Functions for IPC operations • mmap(), munmap()
Posix create/open second argument • How the object is being opened-required • Read-only O_RDONLY • write-only O_WRONLY • read-write O_RDWR • Optional flags • create if does not already exist O_CREATE • exclusive create O_EXCL • nonblocking mode O_NONBLOCK • truncate if already exists O_TRUNC
Mode Constants when a new IPC object is created • S_IRUSR user read • S_IWUSR user write • S_IRGRP group read • S_IWGRP group write • S_IROTH other read • S_IWOTH other write
Include Files • General • #include <sys/types.h> • #include <sys/ipc.h> • Specific IPC types • #include <sys/sem.h> • #include <sys/shm.h> • #include <sys/msg.h>
Key_t keys and ftok() function • Prototype • #include <sys/ipc.h> • key_t ftok(const char *pathname, int id) • returns IPC key if OK, -1 on error • Purpose • Create a unique integer key_t • Same arguments return same value if performed on same computer system
System V Semaphores • Functions • semget() • creates a semaphore set or accesses an existing semaphore set. • semop() • performs operations on one or more of the semaphores • semctl() • performs various control operations on a semaphore
semget - obtain a semaphore set • int semget(key_t key, int nsems, int flag) • key • IPC_PRIVATE - new semaphore object created • integer constant - if no IPC object matches key and IPC_CREAT in flag, new semaphore is created • ftok() can be used to create a semaphore number corresponding to a filename (inode included). • nsems - number of semaphores in set • flag permissions • SEM_R, (SEM_R>>3), (SEM_R>>6) read access • SEM_A, (SEM_A>>3), (SEM_A>>6) alter access
Semop - perform a semaphore operation • Int semop(int semid, struct sembuf *opstr, size_t nops) • semid - semaphore set id as returned by semget() • opstr • an array of sembuf structures • gives the sequence of semaphore operations to be performed • nops • the number of semaphore operations in opstr
Sembuf structure • Struct sembuf { • short semnum; • semaphore number: 0..nsems-1 • short sem_op • semaphore operation to be performed • short sem_flg • operation flags: 0, IPC_NOWAIT, SEM_UNDO • }
Example sembuf struct sembuf ops[2] = { 0, 0, 0, /* wait for [0] to be 0 */ 0, 1, SEM_UNDO /* then inc [0] by 1 */ }; Warning: should not assume order of sembuf elements!
sembuf proper initialization struct sembuf ops[2]; /* declaration */ ops[0].sem_num = 0; /* executable initialization */ ops[0].sem_op = 0; ops[0].sem_flg = 0; ops[1].sem_num = 0; ops[1].sem_op = 1; ops[1].sem_flg = SEM_UNDO;
Semaphore attributes • semval • current value of the semaphore • semncnt • number of threads waiting for semval to be greater than its current value • semzcnt • number of threads waiting for semval to be 0 • semadj • Adjustment value to UNDO a semaphore
Operation of semop • sem_op > 0 • value of sem_op is added to semval • release of resources the semaphore controls • sem_op == 0 • wait until semval is zero • immediate return if already zero • sem_op < 0 • wait until semval ≥ | sem_op | then add sem_op to semval (decreases semval due to negative value) • allocation of resources the semaphore controls
Critical section control • Initial semval is 1 • EnterCriticalSection • sem_op = -1 • sem_flg = 0 • ExitCriticalSection • sem_op = 1 • sem_flg = 0
Allocating Resources • Initial semval is the total number of resources • Allocate n units of resource (may block) • sem_op = -n • sem_flg = 0 (or SEM_UNDO) • Free m units of resource • sem_op = m • sem_flg = 0
Allocating Resources without blocking • Initial semval is the total number of resources • Allocate n units of resource • sem_op = -n • sem_flg = IPC_NOWAIT • semop() returns an error of EAGAIN if insufficient resources
Semctl - control a semaphore • Int semctl(int semid, int semnum, int cmd, /* union semun arg */ ); • semid • identifies the semaphore set • semnum • identifies the member of the semaphore set • cmd • action to perform --see list on following slides • union semun • required for some commands
Union semun definition Union semun { int val; /* used for SETVAL */ struct semid_ds *buf; /* used for IPC_SET and IPC_STAT */ ushort *array; /* used for GETALL and SETALL */ };
Semaphore cmd values • GETVAL - return current value of semval • SETVAL - set value of semval • GETPID - return current value of sempid • GETNCNT - return current value of semnvnt • GETZCNT - return current value of semzcnt • GETALL - return values of semval for all members of the set into arg.array • SETALL - set all values semval for each member of the set from arg.array • IPC_RMID - remove the semaphore set from the system • IPC_SET - set elements of the semid_ds structure • IPC_STAT - return current elements of the semid_ds structure
Semctl examples Union semun arg; arg.val = 1; if (semctl(sem_id, Lock, SETVAL, arg)) { perror(“Setting semaphore Lock to 1 failed.”); return; } arg.val = BUFFSIZE; if (semctl(sem_id, Empties, SETVAL, arg)) { perror(“Setting semaphore Empties to BUFFSIZE failed.”); return; } semctl(sem_id, 3, IPC_RMID); /* Book shows second arg of 0. Probably ignored. */
ipcs and ipcrm programs • Ipcs • Print IPC status information • ipcrm • Remove a semaphore set, message set, or shared memory set.
Posix Semaphores • Sem_open - open a semaphore • sem_close - close a semaphore • sem_unlink -
Sem_open() - create a new named semaphore • Sem_t *sem_open(const char *name, int oflag, /* mode_t mode, unsigned int val*/ ); • name • A pathname-like name, not well defined across systems. • Always #define the name so easily changed. • Good name is /abcdef • oflag • 0 • O_CREATE • O_CREATE | O_EXCL • mode • permissions bits • val • initial value
Sem_close - close a semaphore • Int sem_close(sem_t *sem)
Sem_wait and sem_trywaitWait for a semaphore • Int sem_wait(sem_t *sem) • Decrement value of semaphore by 1, wait if semaphore value is <=0. • int sem_trywait(sem_t *sem) • Same as sem_wait() if semaphore will not block • Returns with return value EAGAIN if would have blocked.
Sem_post and sem_getvalue • Int Sem_post(sem_t *sem) • Increment semaphore value • release waiting process if appropriate • int sem_getvalue(sem_t *sem, int *valp) • get the value of a semaphore
Posix mutex • Static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER • Int pthread_mutex_lock(pthread_mutex *mptr) • int pthread_mutex_trylock(pthread_mutex_t *mptr) • int pthread_mutex_unlock(pthread_mutex_t *mprt); • Enter and exit must be executed by the same thread.
Shared Memory using MMAP() • mmap() • map file or a Posix shared memory object into the address space of a process • munmap() • remove a mapping from the address space of the process • msync() • make sure what is in the disk file is the same as what is in memory.
MMAP - Memory mapped file • Void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) • addr • NULL - kernel chooses starting address • Specific starting address within process • len • number of bytes to map into the address space, starting at offset bytes into the file • prot • protection of the memory-mapped region chosen from PROT_READ, PROT_WRITE, PROT_EXEC, PROT_NONE • PROT_READ | PROT_WRITE gives read-write access
MMAP - continued • Flags • Either MAP_SHARED or MAP_PRIVATE • MAP_PRIVATE - underlying object is not changed • MAP_SHARED - underlying object is changed and changes are visible to other processes • MAP_FIXED ored to above to interpret addr exactly. • Use null addr and do not use MAP_FIXED for portable code. • Fd • file which is mapped into storage. May not be a device (terminal). • Offset • offset into file where mapping begins
Munmap - removes a mapping from the address space • Int munmap(void *addr, size_t len); • addr • address returned by mmap • len • size of the mapped region
Msync - synchronize the file with the memory data • Int msync(void * addr, size_t len, int flags); • addr • address of memory mapped region • len • length of the region • flags • MS_ASYNC - perform asynchronous writes • MS_SYNC - perform synchronous writes • MS_INVALIDATE - invalidate cached storage • Usually addr and len are the whole region, but don’t have to be.
References • W. Richard Stevens, Unix Network Programming, Volume 2, 2nd edition, Prentice-Hall PTR, ISBN 0-13-081081-9, 1999.