1 / 24

Interprocess Communication

Interprocess Communication. Interprocess Communication. Inteprocess communication mechanisms allow arbitrary processes to exchange data and synchronize execution. Messages Data Structure. Pointer to the first and last messages on the linked list. The number of messages.

finlayson
Download Presentation

Interprocess Communication

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Interprocess Communication .

  2. Interprocess Communication Inteprocess communication mechanisms allow arbitrary processes to exchange data and synchronize execution. .

  3. Messages Data Structure • Pointer to the first and last messages on the linked list. • The number of messages. • The total number of bytes in the queue. • The maximum number of messages allowed in the queue. • Permission field for read and write .

  4. Data Area Message Headers Queue Headers Messages Data Structure .

  5. /* one msqid structure for each queue on the system */ • struct msqid_ds { • struct ipc_perm msg_perm; • struct msg *msg_first; /* first message on queue */ • struct msg *msg_last; /* last message in queue */ • time_t msg_stime; /* last msgsnd time */ • time_t msg_rtime; /* last msgrcv time */ • time_t msg_ctime; /* last change time */ • struct wait_queue *wwait; • struct wait_queue *rwait; /* They are used when an operation • on a message queue deems the • process go into a sleep state*/ • ushort msg_cbytes; /* sum of the sizes of all messages */ • ushort msg_qnum; /* maximum number of messages in q*/ • ushort msg_qbytes; /* max number of bytes on queue */ • ushort msg_lspid; /* pid of last msgsnd */ • ushort msg_lrpid; /* last receive pid */ • }; Kernel msqid_ds structure .

  6. #include <sys/types.h> • #include <sys/ipc.h> • #include <sys/msg.h> • A message queue is allocated by a msgget system call : • msqid = msgget (key_t key, int msgflg); • key: an integer or IPC_PRIVATE to assure the return of a a new entry • msgflg: • IPC_CREAT : used to create a new resource if it does not already exist. • IPC_EXCL | IPC_CREAT : used to ensure failure of the call if the resource already exists. • rwxrwxrwx : access permissions. • returns: msqid (an integer used for all further access) on success. -1 on failure. • A message queue is allocated if there is no resource corresponding to the given key. The access permissions specified are then copied into the msg_perm struct and the fields in msqid_ds initialized. The user must use the IPC_CREAT flag or key = IPC_PRIVATE, if a new instance is to be allocated. If a resource corresponding to key already exists, the access permissions are verified. msgget system call .

  7. #include <sys/types.h> • #include <sys/ipc.h> • #include <sys/msg.h> • msgsnd (int id, struct msgbuf *msgp, int size, int flag) • Id:the message id • size:the size of the message • msgp: it is of the following type • struct msgbuf{ • long msgtype; • char mtext []; • } • flag: IPC_NOWAIT bit is of in flag. msgsend sleeps if the number of bytes in the message queue exceeds the maximum, or if the number of messages exceeds the maximum number of the system. msgsend returns immediately. msgsnd system call .

  8. #include <sys/types.h> • #include <sys/ipc.h> • #include <sys/msg.h> • int msgrcv (int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg); • msqid : id obtained by a call to msgget. • msgsz : maximum size of message to receive. • msgp : allocated by user to store the message in. • msgtyp : • = 0 => get first message on queue. • > 0 => get first message of matching type. • < 0 => get message with least type which is <= abs(msgtyp). • msgflg : • IPC_NOWAIT : Return immediately if message not found. • MSG_NOERROR : The message is truncated if it is larger than msgsz. • MSG_EXCEPT : Used with msgtyp > 0 to receive any msg except of specified type. • returns : size of message if found. -1 on error. • . msgrcv system call .

  9. int msgctl (int msqid, int cmd, struct msqid_ds *buf); • msqid : id obtained by a call to msgget. • buf : allocated by user for reading/writing info. • cmd : IPC_STAT, IPC_SET, IPC_RMID. • IPC_STAT, results in the copy of the queue data structure into the user supplied buffer. • IPC_SET, the queue size (msg_qbytes) and the uid, gid, mode (low 9 bits) fields of the msg_perm struct are set from the user supplied values. msg_ctime is updated. • Note that only the super user may increase the limit on the size of a message queue beyond MSGMNB. • IPC_RMID, remove resource. The user must be the owner, creator or super-user. command results in immediate removal of a message queue msgctl system call .

  10. /* results in copying the message queue data structure into buffer */ int get_queue_ds( int qid, struct msgqid_ds *qbuf ) { if( msgctl( qid, IPC_STAT, qbuf) == -1) { return(-1); } return(0); } Get message queue state .

  11. /* The only modifiable item in the data structure is the ipc_perm member. The mode must be passed in as a character array (i.e. ``660''). */ int change_queue_mode( int qid, char *mode ) { struct msqid_ds tmpbuf; /* Retrieve a current copy of the internal data structure */ get_queue_ds( qid, &tmpbuf); /* Change the permissions using an old trick */ sscanf (mode, "%ho", &tmpbuf.msg_perm.mode); /* Update the internal data structure */ if( msgctl( qid, IPC_SET, &tmpbuf) == -1) { return(-1); } return(0); } Change queue mode .

  12. int remove_queue( int qid ) { if( msgctl( qid, IPC_RMID, 0) == -1) { return(-1); } return(0); } Get message queue state .

  13. Check that the sending process has the right permission for the message descriptor. • Check that the message length doesn’t exceed the system limits. • The type is positive integer. • The length of the queue doesn’t have too many bytes. • If all tests succeed, the kernel allocates space for the message, and copies data from user space to system space. • Kernel allocates a space for the header and places the message at the end of the queue. Sets the message header to point to the message data. • The kernel then awakens all processes waiting for the message to be available. msgsnd system call .

  14. msgsnd • Input (1) message queue descriptor • (2) Address of message structure • (3) Size of message • (4) Flags • Output: number of bytes sent\ • { • Check legality of descriptor & permission. • While (not enough space to store message) • { • If (flags specify not to wait) • return; • sleep (until event enough space is available); • } • Allocate space for data and header; • copy data from user space to kernel space; • wakeup all processes waiting to read message from queue • } msgsnd algorithm .

  15. Check that the user has the necessary access rights to the message queue. • If the requested message type is 0, the kernel finds the first message on the linked list. • If the size of the message is less than or equal to the size requested by the user, the kernel copies the message data to the user data structure. • It decrements the counts of messages, and the number of data bytes on the queue, adjust the linked list and free the kernel space for the message. • If processes are waiting to send messages because there was no room in the queue, the kernel awakens them. • If the message is bigger than the msgszspecified by the user, the kernel returns an error and leaves the message in the queue. • If MSG_NOERROR is specified, the kernel truncates the message, returns the requested number of bytes, and removes the entire message from the queue. msgrcv system call .

  16. msgsnd • Input (1) message descriptor • (2) Address of data array of incoming message • (3) Size of data array • (4) Requested message type • (5) Flags • Output: number of bytes in returned message • Check permission • Loop: if (requested message type == 0) • consider first message in the queue • else if (requested message type > 0) • consider first message in the queue with a given value; • else // if requested message type is < 0 • consider first of the lowest typed messages on the queue such that its • type is <= abs (message type) • if (there is a message) • adjust message size or return error if message is too big • copy message from kernel space into user space, unlink message from kernel • // no messages • if (flags specify not to sleep IPC_NOWAIT) • return with error • sleep (event message arrives on queue), • go to loop msgrcv algorithm .

  17. #include <sys/types.h> • #include <sys/ipc.h> • #include <sys/msg.h> • #define MSGKEY 75 • struct msgform{ • long msgtype; • char mtext [256]; • } • Main () • { • struct msgform msg; • int msgid, pid; • pid = getpid (); • msg.mtext [0] = pid; • msg.mtype = 1; • msgid = msgget (MSGKEY,0777); • msgsend (msgid, &msg,sizeof (int),0); • msgrcv (msgid, &msg,256,pid,0); • } msgsnd & msgrcv example .

  18. . A shared segment is described by : struct shmid_ds struct ipc_perm shm_perm; int 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 */ ulong *shm_pages; /* internal page table */ ushort shm_cpid; /* pid, creator */ ushort shm_lpid; /* pid, last operation */ short shm_nattch; /* no. of current attaches */ Shared Memory .

  19. A shared memory segment is allocated by a shmget system call: • #include <sys/ types.h> • #include <sys/ ipc.h> • #include <sys/ shm.h> • int shmget(key_t key, int size, int shmflg); • key :an integer or IPC_PRIVATE • size :size of the segment in bytes (SHMMIN <= size <= SHMMAX). • shmflg : • IPC_CREAT used to create a new resource • IPC_EXCL used with IPC_CREAT to ensure failure if the resource exists. • rwxrwxrwx access permissions. • returns :shmid on success. -1 on failure. • A descriptor for a shared memory segment is allocated if there isn't one corresponding to the given key. The access permissions specified are then copied into the shm_perm struct for the segment along with the user-id etc. The user must use the IPC_CREAT flag or key = IPC_PRIVATE to allocate a new segment. • If the segment already exists, the access permissions are verified, and a check is made to see that it is not marked for destruction. A size is effectively rounded up to a multiple of PAGE_SIZE as shared memory is allocated in pages. . shmget system call .

  20. Maps a shared segment into the process' address space. • #include <sys/ types.h> • #include <sys/ ipc.h> • #include <sys/ shm.h> • char *virt_addr; • virt_addr = shmat (int shmid, char *shmaddr, int shmflg); • shmid :id got from call to shmget. • shmaddr : • requested attach address. if shmaddr is 0 the system finds an unmapped region. If a non-zero value is indicated the value must be page aligned or the user must specify the SHM_RND flag. • shmflg : • SHM_RDONLY :request read-only attach.SHM_RND :attach address is rounded DOWN to a multiple of SHMLBA. • returns:virtual address of attached segment. -1 on failure. • When shmaddr is 0, the attach address is determined by finding an unmapped region in the address range 1G to 1.5G, starting at 1.5G and coming down from there. . shmat system call .

  21. #include <sys/ types.h> #include <sys/ ipc.h> #include <sys/ shm.h> int shmdt (char *shmaddr); shmaddr :attach address of segment (returned by shmat). returns :0 on success. -1 on failure. An attached segment is detached and shm_nattchdecremented. The occupied region in user space is unmapped. The segment is destroyed if it is marked for destruction and shm_nattch is 0. shm_lpid and shm_dtime are updated shmdt system call .

  22. Destroys allocated segments. Reads/Writes the control structures. #include <sys/ types.h> #include <sys/ ipc.h> #include <sys/ shm.h> int shmctl (int shmid, int cmd, struct shmid_ds *buf); shmid :id got from call to shmget. cmd :IPC_STAT, IPC_SET, IPC_RMID IPC_SET :Used to set the owner uid, gid, and shm_perms.mode field. IPC_RMID :The segment is marked destroyed. It is only destroyed on the last detach. IPC_STAT :The shmid_ds structure is copied into the user allocated buffer. buf :used to read (IPC_STAT) or write (IPC_SET) information. returns :0 on success, -1 on failure. The user must execute an IPC_RMID shmctl call to free the memory allocated by the shared segment. Otherwise all the pages faulted in will continue to live in memory or swap. shmctl system call .

  23. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #define SHM_SIZE 1024 /* make it a 1K shared memory segment */ int main (int argc, char *argv[]) { key_t key; int shmid; char *data; int mode; /* make the key: */ if ((key = ftok ("shmdemo.c", 'R')) == -1) { perror("ftok"); exit(1); } Shared memory example .

  24. /* connect to (and possibly create) the segment: */ if ((shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) { perror ("shmget"); exit(1); } /* attach to the segment to get a pointer to it: */ data = shmat (shmid, (void *)0, 0); if (data == (char *)(-1)) { perror ("shmat"); exit(1); } /* read or modify the segment, based on the command line: */ strncpy (data, argv[1], SHM_SIZE); printf ("segment contains: \"%s\"\n", data); /* detach from the segment: */ if (shmdt(data) == -1) { perror ("shmdt"); exit(1); } return 0; } Shared memory (continue) .

More Related