1 / 18

IPC

IPC. Shm & Msg Queue. Shared Memory. Shared Memory is memory that can be seen by more than one process. Normally, when you fork a process, the 2 processes don't access the same memory. Shared Memory is another IPC resource.

reed
Download Presentation

IPC

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. IPC Shm & Msg Queue

  2. Shared Memory • Shared Memory is memory that can be seen by more than one process. Normally, when you fork a process, the 2 processes don't access the same memory. Shared Memory is another IPC resource. • You acquire a shared memory segment by making a call that looks like:shmid = shmget(key, size/* in bytes */, flags);

  3. shmid = shmget(key, size/* in bytes */, flags); • the key must be unique on a given host • the key can be IPC_PRIVATE if you want shared memory that isn't associated with any key. • The flags include permissions and can optionally contain IPC_CREAT and IPC_EXCL. IPC_CREAT creates a shared memory segment if it doesn't already exist. If IPC_EXCL is included with IPC_CREAT then it is considered a failure if the shared memory does already exist. Some valid flag combinations are:06600660 | IPC_CREAT0600 | IPC_CREAT | IPC_EXCL

  4. A negative return code indicates failure and you should check errno (using perror or strerror). • Normally, your program should free up any shared memory that it allocates. However, if your program crashes, your shared memory doesn't automatically get freed up. It stays around and can be seen with theipcs command. • You can free up your shared memory with a command like:ipcrmshmxxxxx

  5. shmat • Once you have a shared memory segment id (shmid), then you next need to to map the memory into your address space. Normally, this should be done with the command char * shm_addr; shm_addr = shmat( shmid, NULL, 0); if (shm_addr == (char *) -1) you have an error. • If you want READ_ONLY access to your shared memory, you can set the third parameter to SHM_RDONLY.

  6. …some more…not to be done..stuff • It is also possible to set the second parameter to the address where you want your shared memory to show up. I would recommend that you don't use this option. The reason people might want this is because they have pointers in their shared memory. This is a bad choice. Normally, pointers can be avoided by properly designing your data structures.

  7. When you get back a good shm_addr, remember it and normally you will want to caste it to data type of your shared memory. Usually its a good idea to create a structthat contains your shared memory. In this way, you can get the compiler to do most of the work computing sizes and figuring out pointers, etc

  8. Once you have gotten this far, you are ready to go. • The normal reason for shared memory is because you have 2 processes that want to share information. This also means that you need to very carefully think through the synchronization issues. 

  9. shm_com.h /* A common header file to describe the shared memory we wish to pass about. */ #define TEXT_SZ 2048 structshared_use_st { intwritten_by_you; char some_text[TEXT_SZ]; };

  10. shm1.c /* Our first program is a consumer. After the headers the shared memory segment (the size of our shared memory structure) is created with a call to shmget, with the IPC_CREAT bit specified. */ #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include "shm_com.h"

  11. int main() { int running = 1; void *shared_memory = (void *)0; structshared_use_st *shared_stuff; intshmid; intmykey = getuid(); srand((unsigned int)getpid()); shmid = shmget((key_t)mykey, sizeof(structshared_use_st), 0666 | IPC_CREAT);

  12. if (shmid == -1) { fprintf(stderr, "shmget failed\n"); exit(EXIT_FAILURE); } /* We now make the shared memory accessible to the program. */ shared_memory = shmat(shmid, (void *)0, 0); if (shared_memory == (void *)-1) { fprintf(stderr, "shmat failed\n"); exit(EXIT_FAILURE); } printf("Memory attached at %X\n", (int)shared_memory);

  13. /* The next portion of the program assigns the shared_memory segment to shared_stuff, which then prints out any text in written_by_you. The loop continues until end is found in written_by_you. The call to sleep forces the consumer to sit in its critical section, which makes the producer wait. */ shared_stuff = (structshared_use_st *)shared_memory; shared_stuff-> written_by_you = 0;

  14. while(running) { if (shared_stuff->written_by_you) { printf("You wrote: %s", shared_stuff->some_text); sleep( rand() % 4 ); /* make the other process wait for us ! */ shared_stuff->written_by_you = 0; if (strncmp(shared_stuff->some_text, "end", 3) == 0) { running = 0; } } }

  15. /* Lastly, the shared memory is detached and then deleted. */ if (shmdt(shared_memory) == -1) { fprintf(stderr, "shmdt failed\n"); exit(EXIT_FAILURE); } if (shmctl(shmid, IPC_RMID, 0) == -1) { fprintf(stderr, "shmctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }

  16. Setting Up a Message Queue Application • You acquire a message queue resource by making a call that looks like:msgid = msgget(key, flags); • the key must be unique on a given host • the key can be IPC_PRIVATE if you want shared memory that isn't associated with any key. • The flags include permissions and can optionally contain IPC_CREAT and IPC_EXCL. IPC_CREAT creates a message queue if it doesn't already exist. If IPC_EXCL is included with IPC_CREAT then it is considered a failure if the message queue does already exist. Some valid flag combinations are:06600660 | IPC_CREAT0600 | IPC_CREAT | IPC_EXCL • A negative return code indicates failure and you should check errno (using perror or strerror).

  17. Normally, your program should free up any message queue that it allocates. However, if your program crashes, your message queue doesn't automatically get freed up. It stays around and can be seen with theipcs command. • To get rid of the message queue resource from your program, code the following: • msgctl(msgid, IPC_RMID, 0); • If your program crashes or doesn't free up the message queue, you can free up your message queue with a command like:ipcrmmsgxxxxx

  18. Receiving from a Message Queue • To receive from a message queue, you use a calling sequence like the following: • retcode = msgrcv(msgid, Buffer_pointer, Buffer_size, msg_to_receive, flags) • msgid is the message Queue identifier returned from the msgget routine. • The Buffer_pointer and Buffer_size are self explainatory • The msg_to_receive indicates what kind of messages to receive. A zero for this parameter indicates all messages are OK to receive. A value > 0 indicates to only receive messages of this type. In this case, the call will only return messages with a a matching msg_to_receive type --- more about this on the msgsend primitive. • If the flags are zero, then the receiver will block if there is nothing to receive in the message queue. All other options are OR'ed in as masking flags: • IPC_NOWAIT indicates that this operation should return an error if there is no packet to receive. In this case we should get a ENOMSG error return code. • MSG_NOERROR indicates that the message should be truncated if necessary to fit the receiving buffer. The error E2BIG is returned when this option is used and the message cannot fit into the buffer.

More Related