1 / 64

2.3 InterProcess Communication (IPC)

2.3 InterProcess Communication (IPC). Part C. IPC methods. Signals Mutex ( MUTual EXclusion ) Semaphores Shared memory Memory mapped files Pipes & named pipes Sockets Message queues MPI (Message Passing Interface) Barriers. Pipes and named pipes. Pipes.

avital
Download Presentation

2.3 InterProcess Communication (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. 2.3 InterProcess Communication (IPC) Part C

  2. IPC methods • Signals • Mutex (MUTualEXclusion) • Semaphores • Shared memory • Memory mapped files • Pipes & named pipes • Sockets • Message queues • MPI (Message Passing Interface) • Barriers

  3. Pipes and named pipes

  4. Pipes Cmd1’s stdout becomes Cmd2’s stdin. one direction only

  5. More Pipes

  6. Too many pipes?!

  7. Pipes via pipe()(child writing to parent) // Excerpt from "Linux Programmer's Guide - Chapter 6." // (C)opyright 1994-1995, Scott Burkett #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main ( intargc, char* argv[] ) { intfd[2], nbytes; pid_tchildpid; char string[] = "Hello, world!\n", readbuffer[80]; pipe( fd ); //fd[0] is opened for reading (input side); // fd[1] is opened for writing (output side).

  8. Pipes via pipe()(child writing to parent) // Excerpt from "Linux Programmer's Guide - Chapter 6." // (C)opyright 1994-1995, Scott Burkett #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main ( intargc, char* argv[] ) { intfd[2], nbytes; pid_tchildpid; char string[] = "Hello, world!\n", readbuffer[80]; pipe( fd ); //fd[0] is opened for reading (input side); // fd[1] is opened for writing (output side). if ( (childpid = fork()) == -1 ) { perror( "fork" ); exit( 1 ); }

  9. Pipes via pipe()(child writing to parent) // Excerpt from "Linux Programmer's Guide - Chapter 6." // (C)opyright 1994-1995, Scott Burkett #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main ( intargc, char* argv[] ) { intfd[2], nbytes; pid_tchildpid; char string[] = "Hello, world!\n", readbuffer[80]; pipe( fd ); //fd[0] is opened for reading (input side); // fd[1] is opened for writing (output side). if ((childpid = fork()) == -1) { perror( "fork" ); exit( 1 ); } if (childpid == 0) { //child process closes input side of pipe, & writes close( fd[0] ); /* Send "string" through the output side of pipe */ write( fd[1], string, (strlen(string)+1) ); } else { //parent process closes output side of pipe, & reads close( fd[1] ); /* Read in a string from the pipe */ nbytes = read( fd[0], readbuffer, sizeof(readbuffer) ); printf( "parent: received string: %s", readbuffer ); } return 0; }

  10. Pipes via pipe()(child writing to parent) // Excerpt from "Linux Programmer's Guide - Chapter 6." // (C)opyright 1994-1995, Scott Burkett #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main ( intargc, char* argv[] ) { intfd[2], nbytes; pid_tchildpid; char string[] = "Hello, world!\n", readbuffer[80]; pipe( fd ); //fd[0] is opened for reading (input side); // fd[1] is opened for writing (output side). if ((childpid = fork()) == -1) { perror( "fork" ); exit( 1 ); } if (childpid == 0) { //child process closes input side of pipe, & writes close( fd[0] ); /* Send "string" through the output side of pipe */ write( fd[1], string, (strlen(string)+1) ); } else { //parent process closes output side of pipe, & reads close( fd[1] ); /* Read in a string from the pipe */ nbytes = read( fd[0], readbuffer, sizeof(readbuffer) ); printf( "parent: received string: %s", readbuffer ); } return 0; } This is child writing to parent. How can we change it to be parent to child?

  11. Pipes via pipe()(parent writing to child) // Excerpt from "Linux Programmer's Guide - Chapter 6." // (C)opyright 1994-1995, Scott Burkett #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main ( intargc, char* argv[] ) { intfd[2], nbytes; pid_tchildpid; char string[] = "Hello, world!\n", readbuffer[80]; pipe( fd ); //fd[0] is opened for reading (input side); // fd[1] is opened for writing (output side). if ((childpid = fork()) == -1) { perror( "fork" ); exit( 1 ); } if (childpid != 0) { //parent process closes input side of pipe, & writes close( fd[0] ); /* Send "string" through the output side of pipe */ write( fd[1], string, (strlen(string)+1) ); } else { //child process closes output side of pipe, & reads close( fd[1] ); /* Read in a string from the pipe */ nbytes = read( fd[0], readbuffer, sizeof(readbuffer) ); printf( "parent: received string: %s", readbuffer ); } return 0; } That was easy!

  12. Pipes between processes (using popen)

  13. Problem • I need to sort data but it’s complicated so I can’t use the regular sort function. • There is a program called sort that can do it for me. • But how can I use it?

  14. Pipes via popen()(pipes to/from processes) // Excerpt from "Linux Programmer's Guide - Chapter 6." // (C)opyright 1994-1995, Scott Burkett #include <stdio.h> #define MAXSTRS 5 int main ( intargc, char* argv[] ) { FILE* pipe_fp; char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie", "delta" }; /* Create one way pipeline with call to popen() */ if (( pipe_fp = popen("sort", "w")) == NULL) { perror( "popen" ); exit( 1 ); } /* Processing loop */ for (intcntr=0; cntr<MAXSTRS; cntr++) { fputs( strings[cntr], pipe_fp ); fputc( '\n', pipe_fp ); } /* Close the pipe */ pclose( pipe_fp ); return 0; } Can be “w” or “r”. Any valid shell command.

  15. Pipes via popen()(pipes to/from processes) // Excerpt from "Linux Programmer's Guide - Chapter 6." // (C)opyright 1994-1995, Scott Burkett #include <stdio.h> #define MAXSTRS 5 int main ( intargc, char* argv[] ) { FILE* pipe_fp; char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie", "delta" }; /* Create one way pipeline with call to popen() */ if (( pipe_fp = popen("sort", "w")) == NULL) { perror( "popen" ); exit( 1 ); } /* Processing loop */ for (intcntr=0; cntr<MAXSTRS; cntr++) { fputs( strings[cntr], pipe_fp); fputc( '\n', pipe_fp); } /* Close the pipe */ pclose( pipe_fp ); return 0; }

  16. Pipes via popen() // Excerpt from "Linux Programmer's Guide - Chapter 6" // (C)opyright 1994-1995, Scott Burkett #include <stdio.h> #define MAXSTRS 5 int main ( intargc, char* argv[] ) { FILE* pipe_fp; char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie", "delta" }; /* Create one way pipeline with call to popen() */ if (( pipe_fp = popen("sort", "w")) == NULL) { perror( "popen" ); exit( 1 ); } /* Processing loop */ for (intcntr=0; cntr<MAXSTRS; cntr++) { fputs( strings[cntr], pipe_fp ); fputc( '\n', pipe_fp ); } /* Close the pipe */ pclose( pipe_fp ); return 0; } How would I modify this to obtain the sorted information?

  17. Pipes via popen() // Excerpt from "Linux Programmer's Guide - Chapter 6" // (C)opyright 1994-1995, Scott Burkett #include <stdio.h> #define MAXSTRS 5 int main ( intargc, char* argv[] ) { FILE* pipe_fp; char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie", "delta" }; /* Create one way pipeline with call to popen() */ if (( pipe_fp = popen("sort > junk.dat", "w")) == NULL) { perror( "popen" ); exit( 1 ); } /* Processing loop */ for (intcntr=0; cntr<MAXSTRS; cntr++) { fputs( strings[cntr], pipe_fp ); fputc( '\n', pipe_fp ); } /* Close the pipe */ pclose( pipe_fp ); return 0; } Any valid shell command. How would I modify this to have obtain the sorted information? This works, but is junk.dat unique?

  18. Named pipes

  19. Named pipes • Named pipes • Use mkfifo command. (What is a FIFO?) • Example • mkfifomypipe • ls –l mypipe • prw------- 1 ggrevera ggrevera 0 Oct 5 21:30 mypipe • ls –l > mypipe • Hangs! Why? • Ctrl-c • ls –l > mypipe & • cat < mypipe • Doesn’t hang! Why?

  20. Using a pipe to communicate to a child’s stdin #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <sys/types.h> #include <unistd.h> int main ( intargc, char* argv[] ) { intfd[ 2 ]; pipe( fd ); //fd[0] is opened for reading (input side); // fd[1] is opened for writing (output side). pid_tchildpid = fork(); assert( childpid != -1 ); if (childpid == 0) { //in child process close( fd[1] ); //MUST close unused side of pipe close( 0 ); //close child's current, default stdin dup( fd[0] ); //duplicate input side of pipe to stdin //create child process //execlp( "cat", "cat", NULL ); //execlp( "sort", "sort", NULL ); execlp( "sort", "sort", "-n", NULL ); perror( "exec failed." ); //should never get here! exit( -1 ); } else { //in parent process close( fd[0] ); //close unused side of pipe //write info to pipe char buff[ 256 ]; for (inti=0; i<=10; i++) { sprintf( buff, "%d \n", i ); write( fd[1], buff, strlen(buff) ); } close( fd[1] ); //indicates that we are done int status; wait( &status ); //wait for child to finish } puts( "done." ); return 0; } parent’s fd[1] ----> child’s stdin

  21. Named pipes • Named pipes • Use mkfifo command. (What is a FIFO?) • Example • mkfifomypipe • ls –l mypipe • prw------- 1 ggrevera ggrevera 0 Oct 5 21:30 mypipe • ls –l > mypipe • Hangs! Why? Because it waits for the reader. • Ctrl-c • ls –l > mypipe & • cat < mypipe • Doesn’t hang! Why? Because the reader executes. • Output on next slide.

  22. Output from named pipe example • ls –l > mypipe & • cat < mypipe total 106412 -rwx------ 1 ggrevera ggrevera 14215 Oct 5 20:45 a.out drwx------ 5 ggrevera ggrevera 4096 Feb 3 2006 csc4025 drwx------ 4 ggrevera ggrevera 4096 Oct 3 09:59 csc4035 -rw------- 1 ggrevera ggrevera 194560 Sep 6 12:52 csc4035.tar -rw------- 1 ggrevera ggrevera 891 Dec 4 2005 dir.cpp . . . -rw------- 1 ggrevera ggrevera 283 Oct 5 20:44 sig.cpp [1]+ Done ls -l >mypipe Why did this finish? Because the reader reads everything.

  23. Named pipes (Windows) • CreatePipe • Creates an anonymous pipe. • CreateNamedPipe • Creates an instance of a named pipe and returns a handle for subsequent pipe operations. A client process connects to a named pipe by using the CreateFile or CallNamedPipe function. • CallNamedPipe • Connects to a message-type pipe, writes to and reads from the pipe, and then closes the pipe. • TransactNamedPipe • Combines the functions that write a message to and read a message from the specified named pipe into a single network operation.

  24. Sockets

  25. Sockets • Communications between systems across the network!

  26. Sockets – client-side Steps: • socket() • creates an endpoint for communication and returns a descriptor • connect() • attempts to make a connection to another socket • call read() and/or write() • similar to an ordinary file

  27. Sockets Grand list of standard port numbers: http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers

  28. Demo • Run cmd (the Windows command prompt). • telnet www.google.com 80 • get<enter> • GET<enter> • Note: HTTP (HyperText Transfer Protocol) is case sensitive!

  29. Sockets – client side

  30. Sockets – client-side(writes a message and reads a response) //---------------------------------------------------------------------- // g++ -O2 -o client.exe client.cpp -lsocket -lnsl //---------------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <netdb.h> #include <sys/types.h> //---------------------------------------------------------------------- static void error ( char* msg ) { perror( msg ); exit( 0 ); } //---------------------------------------------------------------------- int main ( intargc, char* argv[] ) { if (argc < 3) { fprintf( stderr, "usage: %s hostname port \n", argv[0] ); exit( 0 ); } //get port number from command line intportno = atoi( argv[2] ); //create an endpoint for communication intsockfd = socket( AF_INET, SOCK_STREAM, 0 ); if (sockfd < 0) error( "ERROR opening socket" ); ...

  31. Sockets – client-side . . . //get host name from command line structhostent* server = gethostbyname( argv[1] ); if (server == NULL) { fprintf( stderr, "ERROR, no such host \n" ); exit( 0 ); } structsockaddr_inserv_addr; memset( &serv_addr, sizeof(serv_addr), 0 ); serv_addr.sin_family = AF_INET; memcpy( &serv_addr.sin_addr.s_addr, server->h_addr, server->h_length ); serv_addr.sin_port = htons( portno ); if (connect(sockfd, (structsockaddr*)&serv_addr, sizeof(serv_addr)) < 0) error( "ERROR connecting" ); . . . Mention memset and memcpy.

  32. Sockets – client-side . . . printf( "Please enter the message: " ); char buffer[256]; memset( buffer, sizeof(buffer), 0 ); fgets( buffer, sizeof(buffer)-1, stdin ); //fgets includes \n, so we'll remove it (if necessary) if (strlen(buffer) > 0 && buffer[strlen(buffer)-1] == '\n') buffer[ strlen(buffer)-1 ] = 0; int n = write( sockfd, buffer, strlen(buffer)+1 ); //+1 to include \0 if (n < 0) error( "ERROR writing to socket" ); memset( buffer, sizeof(buffer), 0 ); n = read( sockfd, buffer, sizeof(buffer)-1 ); if (n < 0) error( "ERROR reading from socket" ); printf( "response: %s \n", buffer ); return 0; } //----------------------------------------------------------------------

  33. Sockets – client-side (complete code) //---------------------------------------------------------------------- // g++ -O2 -o client.exe client.cpp -lsocket -lnsl //---------------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <netdb.h> #include <sys/types.h> //---------------------------------------------------------------------- static void error ( char* msg ) { perror( msg ); exit( 0 ); } //---------------------------------------------------------------------- int main ( intargc, char* argv[] ) { if (argc < 3) { fprintf( stderr, "usage: %s hostname port \n", argv[0] ); exit( 0 ); } //get port number from command line intportno = atoi( argv[2] ); //create an endpoint for communication intsockfd = socket( AF_INET, SOCK_STREAM, 0 ); if (sockfd < 0) error( "ERROR opening socket" ); //get host name from command line structhostent* server = gethostbyname( argv[1] ); if (server == NULL) { fprintf( stderr, "ERROR, no such host \n" ); exit( 0 ); } structsockaddr_inserv_addr; memset( &serv_addr, sizeof(serv_addr), 0 ); serv_addr.sin_family = AF_INET; memcpy( &serv_addr.sin_addr.s_addr, server->h_addr, server->h_length ); serv_addr.sin_port = htons( portno ); if (connect(sockfd, (structsockaddr*)&serv_addr, sizeof(serv_addr)) < 0) error( "ERROR connecting" ); printf( "Please enter the message: " ); char buffer[256]; memset( buffer, sizeof(buffer), 0 ); fgets( buffer, sizeof(buffer)-1, stdin ); //fgets includes \n, so we'll remove it (if necessary) if (strlen(buffer) > 0 && buffer[strlen(buffer)-1] == '\n') buffer[ strlen(buffer)-1 ] = 0; int n = write( sockfd, buffer, strlen(buffer)+1 ); //+1 to include \0 if (n < 0) error( "ERROR writing to socket" ); memset( buffer, sizeof(buffer), 0 ); n = read( sockfd, buffer, sizeof(buffer)-1 ); if (n < 0) error( "ERROR reading from socket" ); printf( "%s \n", buffer ); return 0; } //----------------------------------------------------------------------

  34. Sockets – server side

  35. Sockets – server-side

  36. Sockets – server-side Steps: • socket() • creates an endpoint for communication and returns a descriptor • bind() • this is called "assigning a name to a socket" • when a socket is created with socket, it exists in a name space (address family) but has no name assigned • listen() • To accept connections, a socket is first created with socket(), a willingness to accept incoming connections and a queue limit for incoming connections are specified with listen, and then the connections are accepted with accept(). • repeat forever: • accept() • fork() a child process that performs reads and/or writes as per ordinary file.

  37. int accept ( int s, structsockaddr* addr, socklen_t* addrlen ); • It . . . • extracts the first connection request on the queue of pending connections, • creates a new connected socket with mostly the same properties as s, • and allocates a new file descriptor for the socket, which is returned. • The newly created socket is no longer in the listening state. • The original socket s is unaffected by this call.

  38. Sockets – server-side /** * \file server2.cpp * \author george j. grevera * \brief A simple server in the internet domain using TCP. Runs on * polaris (but not on scott). * To compile: g++ -o server2.exe server2.cpp -lsocket */ #include <assert.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> static const int Port = 8090; static const bool Verbose = true; //---------------------------------------------------------------------- int main ( intargc, char* argv[] ) { //create an endpoint for communication if (Verbose) puts( "socket()" ); intsockfd = socket( AF_INET, SOCK_STREAM, 0 ); assert( sockfd != -1 ); …

  39. Sockets – server-side … //assign a name to the socket structsockaddr_inserv_addr; memset( &serv_addr, 0, sizeof(serv_addr) ); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons( Port ); if (Verbose) printf( "bind() port %d. \n", Port ); int ret = bind( sockfd, (structsockaddr*)&serv_addr, sizeof(serv_addr) ); assert( ret != -1 ); …

  40. Sockets – server-side … //a willingness to accept incoming connections and a queue // limit for incoming connections are specified with listen if (Verbose) puts( "listen()" ); ret = listen( sockfd, 5 ); assert( ret != -1 ); …

  41. Sockets – server-side … for ( ; ; ) { //extract the first connection request on the queue of // pending connections, create a new connected socket with // mostly the same properties as s, and allocate a new file // descriptor for the socket, which is returned if (Verbose) puts( "parent: accept()" ); structsockaddr_incli_addr; socklen_tclilen = sizeof( cli_addr ); intnewsockfd = accept( sockfd, (structsockaddr*)&cli_addr, &clilen ); assert( newsockfd != -1 ); if (Verbose) puts( "parent: fork()" ); intpid = fork(); if (pid==0) { <child process code here> } close( newsockfd ); //back in parent } return 0; } //---------------------------------------------------------------------- if (Verbose) puts( "child: begin after fork()" ); close( sockfd ); char buffer[ 256 ]; memset( buffer, 0, sizeof(buffer) ); if (Verbose) puts( "child: read()" ); int n = read( newsockfd, buffer, sizeof(buffer)-1 ); assert( n != -1 ); if (Verbose) { printf( "child: here is the message: %s \n", buffer ); puts( "child: write()" ); } char* msg = "I got your message."; n = write( newsockfd, msg, strlen(msg)+1 ); //+1 to include \0 assert( n != -1 ); close( newsockfd ); if (Verbose) puts( "child: end" ); exit( 0 ); //end child

  42. Sockets – server-side (complete code) /** * \file server2.cpp * \author george j. grevera * \brief A simple server in the internet domain using TCP. Runs on * polaris (but not on scott). * To compile: g++ -o server2.exe server2.cpp -lsocket */ #include <assert.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> static const int Port = 8090; static const bool Verbose = true; //---------------------------------------------------------------------- int main ( intargc, char* argv[] ) { //create an endpoint for communication if (Verbose) puts( "socket()" ); intsockfd = socket( AF_INET, SOCK_STREAM, 0 ); assert( sockfd != -1 ); //assign a name to the socket structsockaddr_inserv_addr; memset( &serv_addr, 0, sizeof(serv_addr) ); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons( Port ); if (Verbose) printf( "bind() port %d. \n", Port ); int ret = bind( sockfd, (structsockaddr*)&serv_addr, sizeof(serv_addr) ); assert( ret != -1 ); //a willingness to accept incoming connections and a queue // limit for incoming connections are specified with listen if (Verbose) puts( "listen()" ); ret = listen( sockfd, 5 ); assert( ret != -1 ); for ( ; ; ) { //extract the first connection request on the queue of // pending connections, create a new connected socket with // mostly the same properties as s, and allocate a new file // descriptor for the socket, which is returned if (Verbose) puts( "parent: accept()" ); structsockaddr_incli_addr; socklen_tclilen = sizeof( cli_addr ); intnewsockfd = accept( sockfd, (structsockaddr*)&cli_addr, &clilen ); assert( newsockfd != -1 ); if (Verbose) puts( "parent: fork()" ); intpid = fork(); if (pid==0) { if (Verbose) puts( "child: begin after fork()" ); close( sockfd ); char buffer[ 256 ]; memset( buffer, 0, sizeof(buffer) ); if (Verbose) puts( "child: read()" ); int n = read( newsockfd, buffer, sizeof(buffer)-1 ); assert( n != -1 ); if (Verbose) { printf( "child: here is the message: %s \n", buffer ); puts( "child: write()" ); } char* msg = "I got your message."; n = write( newsockfd, msg, strlen(msg)+1 ); //+1 to include \0 assert( n != -1 ); close( newsockfd ); if (Verbose) puts( "child: end" ); exit( 0 ); } close( newsockfd ); } return 0; } //----------------------------------------------------------------------

  43. Demo • Run server on one system (brunel). • ./server2.exe • Waits for a message from the client, and then responds. • Run client (on same or different system). • ./client.exe brunel 8090 • Prompts for a message, sends message to server, and then outputs response message from server.

  44. Message Queues

  45. Message queues (Unix/Linux) #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> • MSGMAX (Linux) defines the max length of a message (~8K). • Define your message(s). • You may define many different messages of different lengths. structmyMessage { long mtype; //message type … //body of message (you decide) };

  46. Message queues (Unix/Linux) • msgget - begin accessing (and create if necessary) a message queue int msgget ( key_t key, int msgflg ); • msgsnd - send (enqueue) a message int msgsnd ( int msqid, struct msgbuf* msgp, size_t msgsz, int msgflg ); • msgrcv - receive (dequeue) a message ssize_t msgrcv ( int msqid, struct msgbuf* msgp, size_t msgsz, long msgtyp, int msgflg ); • msgctl - misc. message queue control

  47. Example //file: m.h //declare the message structure typedefstruct { enum { mTypeA, mTypeB, mTypeC }; long mtype; char mtext[ 256 ]; } message_buf; #define KEY 1234

  48. Example (sender) //file: mtx.cpp #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "m.h" int main ( intargc, char* argv[] ) { // Get the message queue id for the "name" 1234, which was created by // the server. key_t key = KEY; intmsgflg = IPC_CREAT | 0666; fprintf( stderr, "\nmsgget: Calling msgget(%#lx,%#o) \n", key, msgflg ); intmsqid; if ((msqid = msgget(key, msgflg)) < 0) { perror( "msgget" ); exit( 1 ); } fprintf( stderr, "msgget: msgget succeeded: msqid = %d \n", msqid ); // We'll send message type B message_bufsbuf; sbuf.mtype = sbuf.mTypeB; strcpy( sbuf.mtext, "Did you get this?" ); //size_tbuf_length = strlen(sbuf.mtext) + 1 ; size_tbuf_length = sizeof( message_buf ); // Send a message. if (msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT) < 0) { printf( "%d, %d, %s, %d\n", msqid, sbuf.mtype, sbuf.mtext, buf_length ); perror( "msgsnd" ); exit( 1 ); } printf( "Message: \"%s\" Sent \n", sbuf.mtext ); return 0; }

  49. Example (receiver) //file mrx.cpp #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <stdlib.h> #include "m.h" int main ( intargc, char* argv[] ) { // Get the message queue id for the "name" KEY, which was created by // the server. intmsqid = msgget( KEY, 0666 ); if (msqid < 0) { perror( "msgget" ); exit( 1 ); } // Receive an answer of message type B. message_bufrbuf; if (msgrcv(msqid, &rbuf, sizeof(rbuf), 0, 0) < 0) { perror( "msgrcv" ); exit( 1 ); } // Print the answer. printf( "%d %s \n", rbuf.mtype, rbuf.mtext ); exit( 0 ); }

  50. Message queues (Windows) • Call MQOpenQueue to open the queue with send access. • Call MQSendMessage to send the message. • The MQReceiveMessage function allows you to read messages . When reading messages, you can either peek at (not removing them) or retrieve the messages (removing them) in the queue. Messages can be read either synchronously, asynchronously, or through a transaction. • Call MQCloseQueue to close the opened queue and free resources.

More Related