2.3 interprocess communication (ipc)

64
2.3 InterProcess 2.3 InterProcess Communication Communication (IPC) (IPC) Part C Part C

Upload: avital

Post on 07-Feb-2016

110 views

Category:

Documents


0 download

DESCRIPTION

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. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 2.3 InterProcess Communication (IPC)

2.3 InterProcess 2.3 InterProcess Communication (IPC)Communication (IPC)

Part CPart C

Page 2: 2.3 InterProcess Communication (IPC)

IPC methodsIPC methods1.1. SignalsSignals2.2. Mutex (MUTual EXclusion)Mutex (MUTual EXclusion)3.3. SemaphoresSemaphores4.4. Shared memoryShared memory5.5. Memory mapped filesMemory mapped files6.6. Pipes & named pipesPipes & named pipes7.7. SocketsSockets8.8. Message queuesMessage queues9.9. MPI (Message Passing Interface)MPI (Message Passing Interface)10.10.BarriersBarriers

Page 3: 2.3 InterProcess Communication (IPC)

Pipes and named Pipes and named pipespipes

Page 4: 2.3 InterProcess Communication (IPC)

PipesPipes

one direction only

Cmd1’s stdout becomes Cmd2’s stdin.

Page 5: 2.3 InterProcess Communication (IPC)

More PipesMore Pipes

Page 6: 2.3 InterProcess Communication (IPC)

Too many pipes?!Too many pipes?!

Page 7: 2.3 InterProcess Communication (IPC)

// Excerpt from "Linux Programmer's Guide - Chapter 6."// Excerpt from "Linux Programmer's Guide - Chapter 6."// (C)opyright 1994-1995, Scott Burkett// (C)opyright 1994-1995, Scott Burkett#include <stdio.h>#include <stdio.h>#include <unistd.h>#include <unistd.h>#include <sys/types.h>#include <sys/types.h>

int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { int fd[2]int fd[2], nbytes;, nbytes; pid_t childpid;pid_t childpid; char string[] = "Hello, world!\n", readbuffer[80];char string[] = "Hello, world!\n", readbuffer[80]; pipe( fd );pipe( fd ); //fd[0] is opened for reading (input side);//fd[0] is opened for reading (input side);

// fd[1] is opened for writing (output side).// fd[1] is opened for writing (output side).

Pipes via pipe()Pipes via pipe()(child writing to parent)(child writing to parent)

Page 8: 2.3 InterProcess Communication (IPC)

// Excerpt from "Linux Programmer's Guide - Chapter 6."// Excerpt from "Linux Programmer's Guide - Chapter 6."// (C)opyright 1994-1995, Scott Burkett// (C)opyright 1994-1995, Scott Burkett#include <stdio.h>#include <stdio.h>#include <unistd.h>#include <unistd.h>#include <sys/types.h>#include <sys/types.h>

int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { int fd[2], nbytes;int fd[2], nbytes; pid_t childpid;pid_t childpid; char string[] = "Hello, world!\n", readbuffer[80];char string[] = "Hello, world!\n", readbuffer[80]; pipe( fd );pipe( fd ); //fd[0] is opened for reading (input side);//fd[0] is opened for reading (input side);

// fd[1] is opened for writing (output side).// fd[1] is opened for writing (output side). if ( (childpid = fork()) == -1 ) {if ( (childpid = fork()) == -1 ) { perror( "fork" );perror( "fork" ); exit( 1 );exit( 1 ); }}

Pipes via pipe()Pipes via pipe()(child writing to parent)(child writing to parent)

Page 9: 2.3 InterProcess Communication (IPC)

// Excerpt from "Linux Programmer's Guide - Chapter 6."// Excerpt from "Linux Programmer's Guide - Chapter 6."// (C)opyright 1994-1995, Scott Burkett// (C)opyright 1994-1995, Scott Burkett#include <stdio.h>#include <stdio.h>#include <unistd.h>#include <unistd.h>#include <sys/types.h>#include <sys/types.h>

int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { int fd[2], nbytes;int fd[2], nbytes; pid_t childpid;pid_t childpid; char string[] = "Hello, world!\n", readbuffer[80];char string[] = "Hello, world!\n", readbuffer[80]; pipe( fd );pipe( fd ); //fd[0] is opened for reading (input side);//fd[0] is opened for reading (input side);

// fd[1] is opened for writing (output side).// fd[1] is opened for writing (output side). if ((childpid = fork()) == -1) {if ((childpid = fork()) == -1) { perror( "fork" );perror( "fork" ); exit( 1 );exit( 1 ); }} if (childpid == 0) { //child process closes input side of pipe, & if (childpid == 0) { //child process closes input side of pipe, &

writeswrites close( fd[0] );close( fd[0] ); /* Send "string" through the output side of pipe *//* Send "string" through the output side of pipe */ write( fd[1], string, (strlen(string)+1) );write( fd[1], string, (strlen(string)+1) ); }} else { //parent process closes output side of pipe, & reads else { //parent process closes output side of pipe, & reads close( fd[1] );close( fd[1] ); /* Read in a string from the pipe *//* Read in a string from the pipe */ nbytes = read( fd[0], readbuffer, sizeof(readbuffer) );nbytes = read( fd[0], readbuffer, sizeof(readbuffer) ); printf( "parent: received string: %s", readbuffer );printf( "parent: received string: %s", readbuffer ); }} return 0;return 0;}}

Pipes via pipe()Pipes via pipe()(child writing to parent)(child writing to parent)

Page 10: 2.3 InterProcess Communication (IPC)

// Excerpt from "Linux Programmer's Guide - Chapter 6."// Excerpt from "Linux Programmer's Guide - Chapter 6."// (C)opyright 1994-1995, Scott Burkett// (C)opyright 1994-1995, Scott Burkett#include <stdio.h>#include <stdio.h>#include <unistd.h>#include <unistd.h>#include <sys/types.h>#include <sys/types.h>

int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { int fd[2], nbytes;int fd[2], nbytes; pid_t childpid;pid_t childpid; char string[] = "Hello, world!\n", readbuffer[80];char string[] = "Hello, world!\n", readbuffer[80]; pipe( fd );pipe( fd ); //fd[0] is opened for reading (input side);//fd[0] is opened for reading (input side);

// fd[1] is opened for writing (output side).// fd[1] is opened for writing (output side). if ((childpid = fork()) == -1) {if ((childpid = fork()) == -1) { perror( "fork" );perror( "fork" ); exit( 1 );exit( 1 ); }} if (childpid == 0) { //child process closes input side of pipe, & writesif (childpid == 0) { //child process closes input side of pipe, & writes close( fd[0] );close( fd[0] ); /* Send "string" through the output side of pipe *//* Send "string" through the output side of pipe */ write( fd[1], string, (strlen(string)+1) );write( fd[1], string, (strlen(string)+1) ); }} else { //parent process closes output side of pipe, & reads else { //parent process closes output side of pipe, & reads close( fd[1] );close( fd[1] ); /* Read in a string from the pipe *//* Read in a string from the pipe */ nbytes = read( fd[0], readbuffer, sizeof(readbuffer) );nbytes = read( fd[0], readbuffer, sizeof(readbuffer) ); printf( "parent: received string: %s", readbuffer );printf( "parent: received string: %s", readbuffer ); }} return 0;return 0;}}

Pipes via pipe()Pipes via pipe()(child writing to parent)(child writing to parent)

This is child writing to parent.

How can we change it to be parent to child?

Page 11: 2.3 InterProcess Communication (IPC)

// Excerpt from "Linux Programmer's Guide - Chapter 6."// Excerpt from "Linux Programmer's Guide - Chapter 6."// (C)opyright 1994-1995, Scott Burkett// (C)opyright 1994-1995, Scott Burkett#include <stdio.h>#include <stdio.h>#include <unistd.h>#include <unistd.h>#include <sys/types.h>#include <sys/types.h>

int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { int fd[2], nbytes;int fd[2], nbytes; pid_t childpid;pid_t childpid; char string[] = "Hello, world!\n", readbuffer[80];char string[] = "Hello, world!\n", readbuffer[80]; pipe( fd );pipe( fd ); //fd[0] is opened for reading (input side);//fd[0] is opened for reading (input side);

// fd[1] is opened for writing (output side).// fd[1] is opened for writing (output side). if ((childpid = fork()) == -1) {if ((childpid = fork()) == -1) { perror( "fork" );perror( "fork" ); exit( 1 );exit( 1 ); }} if (childpid != 0) { //parent process closes input side of pipe, & writesif (childpid != 0) { //parent process closes input side of pipe, & writes close( fd[0] );close( fd[0] ); /* Send "string" through the output side of pipe *//* Send "string" through the output side of pipe */ write( fd[1], string, (strlen(string)+1) );write( fd[1], string, (strlen(string)+1) ); } else { //child process closes output side of pipe, & reads} else { //child process closes output side of pipe, & reads close( fd[1] );close( fd[1] ); /* Read in a string from the pipe *//* Read in a string from the pipe */ nbytes = read( fd[0], readbuffer, sizeof(readbuffer) );nbytes = read( fd[0], readbuffer, sizeof(readbuffer) ); printf( "parent: received string: %s", readbuffer );printf( "parent: received string: %s", readbuffer ); }} return 0;return 0;}}

Pipes via pipe()Pipes via pipe()(parent writing to child)(parent writing to child)

That was easy!

Page 12: 2.3 InterProcess Communication (IPC)

PIPES BETWEEN PIPES BETWEEN PROCESSES (USING PROCESSES (USING POPEN)POPEN)

Page 13: 2.3 InterProcess Communication (IPC)

ProblemProblem► I need to sort data but it’s complicated I need to sort data but it’s complicated

so I can’t use the regular sort function.so I can’t use the regular sort function.

►There is a program called There is a program called sortsort that can that can do it for me.do it for me.

►But how can I use it?But how can I use it?

Page 14: 2.3 InterProcess Communication (IPC)

// Excerpt from "Linux Programmer's Guide - Chapter 6."// Excerpt from "Linux Programmer's Guide - Chapter 6."// (C)opyright 1994-1995, Scott Burkett// (C)opyright 1994-1995, Scott Burkett#include <stdio.h>#include <stdio.h>#define MAXSTRS 5#define MAXSTRS 5int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { FILE* pipe_fp;FILE* pipe_fp; char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie", char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie",

"delta" };"delta" };

/* Create one way pipeline with call to popen() *//* Create one way pipeline with call to popen() */ if (if (( pipe_fp = popen("sort", "w"))( pipe_fp = popen("sort", "w")) == NULL) { == NULL) { perror( "popen" );perror( "popen" ); exit( 1 );exit( 1 ); }} /* Processing loop *//* Processing loop */ for (int cntr=0; cntr<MAXSTRS; cntr++) {for (int cntr=0; cntr<MAXSTRS; cntr++) { fputs( strings[cntr], pipe_fp );fputs( strings[cntr], pipe_fp ); fputc( '\n', pipe_fp );fputc( '\n', pipe_fp ); }} /* Close the pipe *//* Close the pipe */ pclose( pipe_fp );pclose( pipe_fp ); return 0;return 0;}}

Pipes via popen()Pipes via popen()(pipes to/from processes)(pipes to/from processes)

Any valid shell command.

Can be “w” or “r”.

Page 15: 2.3 InterProcess Communication (IPC)

// Excerpt from "Linux Programmer's Guide - Chapter 6."// Excerpt from "Linux Programmer's Guide - Chapter 6."// (C)opyright 1994-1995, Scott Burkett// (C)opyright 1994-1995, Scott Burkett#include <stdio.h>#include <stdio.h>#define MAXSTRS 5#define MAXSTRS 5int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { FILE* pipe_fp;FILE* pipe_fp; char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie", char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie",

"delta" };"delta" };

/* Create one way pipeline with call to popen() *//* Create one way pipeline with call to popen() */ if (( pipe_fp = popen("sort", "w")) == NULL) {if (( pipe_fp = popen("sort", "w")) == NULL) { perror( "popen" );perror( "popen" ); exit( 1 );exit( 1 ); }} /* Processing loop *//* Processing loop */ for (int cntr=0; cntr<MAXSTRS; cntr++) {for (int cntr=0; cntr<MAXSTRS; cntr++) { fputs( strings[cntr], fputs( strings[cntr], pipe_fp pipe_fp );); fputc( '\n', fputc( '\n', pipe_fp pipe_fp );); }} /* Close the pipe *//* Close the pipe */ pclose( pipe_fp );pclose( pipe_fp ); return 0;return 0;}}

Pipes via popen()Pipes via popen()(pipes to/from processes)(pipes to/from processes)

Page 16: 2.3 InterProcess Communication (IPC)

// Excerpt from "Linux Programmer's Guide - Chapter 6"// Excerpt from "Linux Programmer's Guide - Chapter 6"// (C)opyright 1994-1995, Scott Burkett// (C)opyright 1994-1995, Scott Burkett#include <stdio.h>#include <stdio.h>#define MAXSTRS 5#define MAXSTRS 5int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { FILE* pipe_fp;FILE* pipe_fp; char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie", char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie",

"delta" };"delta" };

/* Create one way pipeline with call to popen() *//* Create one way pipeline with call to popen() */ if (( pipe_fp = popen("sort", "w")) == NULL) {if (( pipe_fp = popen("sort", "w")) == NULL) { perror( "popen" );perror( "popen" ); exit( 1 );exit( 1 ); }} /* Processing loop *//* Processing loop */ for (int cntr=0; cntr<MAXSTRS; cntr++) {for (int cntr=0; cntr<MAXSTRS; cntr++) { fputs( strings[cntr], pipe_fp );fputs( strings[cntr], pipe_fp ); fputc( '\n', pipe_fp );fputc( '\n', pipe_fp ); }} /* Close the pipe *//* Close the pipe */ pclose( pipe_fp );pclose( pipe_fp ); return 0;return 0;}}

Pipes via popen()Pipes via popen()

How would I modify this to obtain the sorted information?

Page 17: 2.3 InterProcess Communication (IPC)

// Excerpt from "Linux Programmer's Guide - Chapter 6"// Excerpt from "Linux Programmer's Guide - Chapter 6"// (C)opyright 1994-1995, Scott Burkett// (C)opyright 1994-1995, Scott Burkett#include <stdio.h>#include <stdio.h>#define MAXSTRS 5#define MAXSTRS 5int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { FILE* pipe_fp;FILE* pipe_fp; char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie", char* strings[ MAXSTRS ] = { "echo", "bravo", "alpha", "charlie",

"delta" };"delta" };

/* Create one way pipeline with call to popen() *//* Create one way pipeline with call to popen() */ if (( pipe_fp = popen("sort > junk.dat", "w")) == NULL) {if (( pipe_fp = popen("sort > junk.dat", "w")) == NULL) { perror( "popen" );perror( "popen" ); exit( 1 );exit( 1 ); }} /* Processing loop *//* Processing loop */ for (int cntr=0; cntr<MAXSTRS; cntr++) {for (int cntr=0; cntr<MAXSTRS; cntr++) { fputs( strings[cntr], pipe_fp );fputs( strings[cntr], pipe_fp ); fputc( '\n', pipe_fp );fputc( '\n', pipe_fp ); }} /* Close the pipe *//* Close the pipe */ pclose( pipe_fp );pclose( pipe_fp ); return 0;return 0;}}

Pipes via popen()Pipes via popen()

Any valid shell command.

How would I modify this to have obtain the sorted information?This works, but is junk.dat unique?

Page 18: 2.3 InterProcess Communication (IPC)

NAMED PIPESNAMED PIPES

Page 19: 2.3 InterProcess Communication (IPC)

Named pipesNamed pipes►Named pipesNamed pipes

Use mkfifo command. (What is a FIFO?)Use mkfifo command. (What is a FIFO?) ExampleExample

►mkfifo mypipemkfifo mypipe► ls –l mypipels –l mypipe

pprw------- 1 ggrevera ggrevera 0 Oct 5 21:30 mypiperw------- 1 ggrevera ggrevera 0 Oct 5 21:30 mypipe► ls –l > mypipels –l > mypipe

Hangs! Why?Hangs! Why? Ctrl-cCtrl-c

► ls –l > mypipe &ls –l > mypipe &►cat < mypipecat < mypipe

Doesn’t hang! Why?Doesn’t hang! Why?

Page 20: 2.3 InterProcess Communication (IPC)

Using a pipe to communicate Using a pipe to communicate to a child’s stdinto a child’s stdin

#include <assert.h>#include <assert.h>#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>#include <strings.h>#include <strings.h>#include <sys/types.h>#include <sys/types.h>#include <unistd.h>#include <unistd.h>

int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { int fd[ 2 ];int fd[ 2 ]; pipe( fd );pipe( fd ); //fd[0] is opened for reading (input side);//fd[0] is opened for reading (input side);

// fd[1] is opened for writing (output side).// fd[1] is opened for writing (output side). pid_t childpid = fork();pid_t childpid = fork(); assert( childpid != -1 );assert( childpid != -1 ); if (childpid == 0) { //in child processif (childpid == 0) { //in child process close( fd[1] ); //MUST close unused side of pipeclose( fd[1] ); //MUST close unused side of pipe

close( 0 ); //close child's current, default stdinclose( 0 ); //close child's current, default stdin dup( fd[0] ); //duplicate input side of pipe to stdindup( fd[0] ); //duplicate input side of pipe to stdin

//create child process//create child process //execlp( "cat", "cat", NULL );//execlp( "cat", "cat", NULL ); //execlp( "sort", "sort", NULL );//execlp( "sort", "sort", NULL );

execlp( "sort", "sort", "-n", NULL );execlp( "sort", "sort", "-n", NULL );

perror( "exec failed." ); //should never get here!perror( "exec failed." ); //should never get here! exit( -1 );exit( -1 ); } else { //in parent process} else { //in parent process close( fd[0] ); //close unused side of pipeclose( fd[0] ); //close unused side of pipe

//write info to pipe//write info to pipe char buff[ 256 ];char buff[ 256 ]; for (int i=0; i<=10; i++) {for (int i=0; i<=10; i++) { sprintf( buff, "%d \n", i );sprintf( buff, "%d \n", i ); write( fd[1], buff, strlen(buff) );write( fd[1], buff, strlen(buff) ); }}

close( fd[1] ); //indicates that we are doneclose( fd[1] ); //indicates that we are done int status;int status; wait( &status ); //wait for child to finishwait( &status ); //wait for child to finish }}

puts( "done." );puts( "done." ); return 0;return 0;}}

parent’s fd[1] ----> child’s stdin

Page 21: 2.3 InterProcess Communication (IPC)

Named pipesNamed pipes►Named pipesNamed pipes

Use mkfifo command. (What is a FIFO?)Use mkfifo command. (What is a FIFO?) ExampleExample

►mkfifo mypipemkfifo mypipe► ls –l mypipels –l mypipe

pprw------- 1 ggrevera ggrevera 0 Oct 5 21:30 mypiperw------- 1 ggrevera ggrevera 0 Oct 5 21:30 mypipe► ls –l > mypipels –l > mypipe

Hangs! Why? Hangs! Why? Because it waits for the reader.Because it waits for the reader. Ctrl-cCtrl-c

► ls –l > mypipe &ls –l > mypipe &►cat < mypipecat < mypipe

Doesn’t hang! Why? Doesn’t hang! Why? Because the reader executes.Because the reader executes. Output on next slide.Output on next slide.

Page 22: 2.3 InterProcess Communication (IPC)

Output from named pipe Output from named pipe exampleexample

► ls –l > mypipe &ls –l > mypipe &► cat < mypipecat < mypipe

total 106412total 106412-rwx------ 1 ggrevera ggrevera 14215 Oct 5 20:45 a.out-rwx------ 1 ggrevera ggrevera 14215 Oct 5 20:45 a.outdrwx------ 5 ggrevera ggrevera 4096 Feb 3 2006 csc4025drwx------ 5 ggrevera ggrevera 4096 Feb 3 2006 csc4025drwx------ 4 ggrevera ggrevera 4096 Oct 3 09:59 csc4035drwx------ 4 ggrevera ggrevera 4096 Oct 3 09:59 csc4035-rw------- 1 ggrevera ggrevera 194560 Sep 6 12:52 csc4035.tar-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 891 Dec 4 2005 dir.cpp......-rw------- 1 ggrevera ggrevera 283 Oct 5 20:44 sig.cpp-rw------- 1 ggrevera ggrevera 283 Oct 5 20:44 sig.cpp

[1]+ Done ls -l >mypipe[1]+ Done ls -l >mypipe

Why did this finish? Because the reader reads everything.Why did this finish? Because the reader reads everything.

Page 23: 2.3 InterProcess Communication (IPC)

Named pipes (Windows)Named pipes (Windows)► CreatePipeCreatePipe

Creates an anonymous pipe.Creates an anonymous pipe.► CreateNamedPipeCreateNamedPipe

Creates an instance of a named pipe and returns a handle for Creates an instance of a named pipe and returns a handle for subsequent pipe operations. A client process connects to a subsequent pipe operations. A client process connects to a named pipe by using the CreateFile or CallNamedPipe function.named pipe by using the CreateFile or CallNamedPipe function.

► CallNamedPipeCallNamedPipe Connects to a message-type pipe, writes to and reads from the Connects to a message-type pipe, writes to and reads from the

pipe, and then closes the pipe.pipe, and then closes the pipe.► TransactNamedPipeTransactNamedPipe

Combines the functions that write a message to and read a Combines the functions that write a message to and read a message from the specified named pipe into a single network message from the specified named pipe into a single network operation.operation.

Page 24: 2.3 InterProcess Communication (IPC)

SocketsSockets

Page 25: 2.3 InterProcess Communication (IPC)

SocketsSockets►Communications between systems Communications between systems

across the network!across the network!

Page 26: 2.3 InterProcess Communication (IPC)

Sockets – client-sideSockets – client-sideSteps:Steps:

1.1. socket()socket() creates an endpoint for communication and creates an endpoint for communication and

returns a descriptorreturns a descriptor

2.2. connect()connect() attempts to make a connection to another socketattempts to make a connection to another socket

3.3. call read() and/or write()call read() and/or write() similar to an ordinary filesimilar to an ordinary file

Page 27: 2.3 InterProcess Communication (IPC)

SocketsSockets

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

Page 28: 2.3 InterProcess Communication (IPC)

DemoDemo►Run cmd (the Windows command prompt).Run cmd (the Windows command prompt).►telnet www.google.com 80telnet www.google.com 80►get<enter>get<enter>

►GET<enter>GET<enter>

►Note: HTTP (HyperText Transfer Protocol) Note: HTTP (HyperText Transfer Protocol) is case sensitive!is case sensitive!

Page 29: 2.3 InterProcess Communication (IPC)

SOCKETS – CLIENT SIDESOCKETS – CLIENT SIDE

Page 30: 2.3 InterProcess Communication (IPC)

//----------------------------------------------------------------------//----------------------------------------------------------------------// g++ -O2 -o client.exe client.cpp -lsocket -lnsl// g++ -O2 -o client.exe client.cpp -lsocket -lnsl//----------------------------------------------------------------------//----------------------------------------------------------------------#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>#include <strings.h>#include <strings.h>#include <sys/socket.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/in.h>#include <unistd.h>#include <unistd.h>#include <netdb.h>#include <netdb.h>#include <sys/types.h>#include <sys/types.h>//----------------------------------------------------------------------//----------------------------------------------------------------------static void error ( char* msg ) {static void error ( char* msg ) { perror( msg );perror( msg ); exit( 0 );exit( 0 );}}//----------------------------------------------------------------------//----------------------------------------------------------------------int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) {

if (argc < 3) {if (argc < 3) { fprintf( stderr, "usage: %s hostname port \n", argv[0] );fprintf( stderr, "usage: %s hostname port \n", argv[0] ); exit( 0 );exit( 0 ); }}

//get port number from command line//get port number from command line int portno = atoi( argv[2] );int portno = atoi( argv[2] );

//create an endpoint for communication//create an endpoint for communication int sockfd = socket( AF_INET, SOCK_STREAM, 0 );int sockfd = socket( AF_INET, SOCK_STREAM, 0 ); if (sockfd < 0) error( "ERROR opening socket" );if (sockfd < 0) error( "ERROR opening socket" );......

Sockets – client-sideSockets – client-side(writes a message and reads a (writes a message and reads a

response)response)

Page 31: 2.3 InterProcess Communication (IPC)

Sockets – client-sideSockets – client-side...... //get host name from command line//get host name from command line struct hostent* server = gethostbyname( argv[1] );struct hostent* server = gethostbyname( argv[1] ); if (server == NULL) {if (server == NULL) { fprintf( stderr, "ERROR, no such host \n" );fprintf( stderr, "ERROR, no such host \n" ); exit( 0 );exit( 0 ); }}

struct sockaddr_in serv_addr;struct sockaddr_in serv_addr; memset( &serv_addr, sizeof(serv_addr), 0 );memset( &serv_addr, sizeof(serv_addr), 0 ); serv_addr.sin_family = AF_INET;serv_addr.sin_family = AF_INET; memcpy( &serv_addr.sin_addr.s_addr, server->h_addr, server-memcpy( &serv_addr.sin_addr.s_addr, server->h_addr, server-

>h_length );>h_length ); serv_addr.sin_port = htons( portno );serv_addr.sin_port = htons( portno ); if (if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)) < 0) error( "ERROR connecting" );error( "ERROR connecting" );......

Mention memset and memcpy.

Page 32: 2.3 InterProcess Communication (IPC)

Sockets – client-sideSockets – client-side...... printf( "Please enter the message: " );printf( "Please enter the message: " ); char buffer[256];char buffer[256]; memset( buffer, sizeof(buffer), 0 );memset( buffer, sizeof(buffer), 0 ); fgets( buffer, sizeof(buffer)-1, stdin );fgets( buffer, sizeof(buffer)-1, stdin ); //fgets includes \n, so we'll remove it (if necessary)//fgets includes \n, so we'll remove it (if necessary) if (strlen(buffer) > 0 && buffer[strlen(buffer)-1] == '\n')if (strlen(buffer) > 0 && buffer[strlen(buffer)-1] == '\n') buffer[ strlen(buffer)-1 ] = 0;buffer[ strlen(buffer)-1 ] = 0;

int n = write( sockfd, buffer, strlen(buffer)+1 ); int n = write( sockfd, buffer, strlen(buffer)+1 ); //+1 to include \0//+1 to include \0 if (n < 0) error( "ERROR writing to socket" );if (n < 0) error( "ERROR writing to socket" );

memset( buffer, sizeof(buffer), 0 );memset( buffer, sizeof(buffer), 0 ); n = read( sockfd, buffer, sizeof(buffer)-1 );n = read( sockfd, buffer, sizeof(buffer)-1 ); if (n < 0) error( "ERROR reading from socket" );if (n < 0) error( "ERROR reading from socket" ); printf( "response: %s \n", buffer );printf( "response: %s \n", buffer );

return 0;return 0;}}//----------------------------------------------------------------------//----------------------------------------------------------------------

Page 33: 2.3 InterProcess Communication (IPC)

Sockets – client-side Sockets – client-side (complete code)(complete code)

//----------------------------------------------------------------------//----------------------------------------------------------------------// g++ -O2 -o client.exe client.cpp -lsocket -lnsl// g++ -O2 -o client.exe client.cpp -lsocket -lnsl//----------------------------------------------------------------------//----------------------------------------------------------------------#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>#include <strings.h>#include <strings.h>#include <sys/socket.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/in.h>#include <unistd.h>#include <unistd.h>#include <netdb.h>#include <netdb.h>#include <sys/types.h>#include <sys/types.h>//----------------------------------------------------------------------//----------------------------------------------------------------------static void error ( char* msg ) {static void error ( char* msg ) { perror( msg );perror( msg ); exit( 0 );exit( 0 );}}//----------------------------------------------------------------------//----------------------------------------------------------------------int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) {

if (argc < 3) {if (argc < 3) { fprintf( stderr, "usage: %s hostname port \n", argv[0] );fprintf( stderr, "usage: %s hostname port \n", argv[0] ); exit( 0 );exit( 0 ); }}

//get port number from command line//get port number from command line int portno = atoi( argv[2] );int portno = atoi( argv[2] );

//create an endpoint for communication//create an endpoint for communication int sockfd = socket( AF_INET, SOCK_STREAM, 0 );int sockfd = socket( AF_INET, SOCK_STREAM, 0 ); if (sockfd < 0) error( "ERROR opening socket" );if (sockfd < 0) error( "ERROR opening socket" );

//get host name from command line//get host name from command line struct hostent* server = gethostbyname( argv[1] );struct hostent* server = gethostbyname( argv[1] ); if (server == NULL) {if (server == NULL) { fprintf( stderr, "ERROR, no such host \n" );fprintf( stderr, "ERROR, no such host \n" ); exit( 0 );exit( 0 ); }}

struct sockaddr_in serv_addr;struct sockaddr_in serv_addr; memset( &serv_addr, sizeof(serv_addr), 0 );memset( &serv_addr, sizeof(serv_addr), 0 ); serv_addr.sin_family = AF_INET;serv_addr.sin_family = AF_INET; memcpy( &serv_addr.sin_addr.s_addr, server->h_addr, server->h_length );memcpy( &serv_addr.sin_addr.s_addr, server->h_addr, server->h_length ); serv_addr.sin_port = htons( portno );serv_addr.sin_port = htons( portno ); if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) error( "ERROR connecting" );error( "ERROR connecting" );

printf( "Please enter the message: " );printf( "Please enter the message: " ); char buffer[256];char buffer[256]; memset( buffer, sizeof(buffer), 0 );memset( buffer, sizeof(buffer), 0 ); fgets( buffer, sizeof(buffer)-1, stdin );fgets( buffer, sizeof(buffer)-1, stdin ); //fgets includes \n, so we'll remove it (if necessary)//fgets includes \n, so we'll remove it (if necessary) if (strlen(buffer) > 0 && buffer[strlen(buffer)-1] == '\n')if (strlen(buffer) > 0 && buffer[strlen(buffer)-1] == '\n') buffer[ strlen(buffer)-1 ] = 0;buffer[ strlen(buffer)-1 ] = 0;

int n = write( sockfd, buffer, strlen(buffer)+1 ); //+1 to include \0int n = write( sockfd, buffer, strlen(buffer)+1 ); //+1 to include \0 if (n < 0) error( "ERROR writing to socket" );if (n < 0) error( "ERROR writing to socket" );

memset( buffer, sizeof(buffer), 0 );memset( buffer, sizeof(buffer), 0 ); n = read( sockfd, buffer, sizeof(buffer)-1 );n = read( sockfd, buffer, sizeof(buffer)-1 ); if (n < 0) error( "ERROR reading from socket" );if (n < 0) error( "ERROR reading from socket" ); printf( "%s \n", buffer );printf( "%s \n", buffer );

return 0;return 0;}}//----------------------------------------------------------------------//----------------------------------------------------------------------

Page 34: 2.3 InterProcess Communication (IPC)

SOCKETS – SERVER SIDESOCKETS – SERVER SIDE

Page 35: 2.3 InterProcess Communication (IPC)

Sockets – server-sideSockets – server-side

Page 36: 2.3 InterProcess Communication (IPC)

Sockets – server-sideSockets – server-sideSteps:Steps:

1.1. socket()socket() creates an endpoint for communication and returns a creates an endpoint for communication and returns a

descriptordescriptor2.2. bind()bind()

this is called "assigning a name to a socket"this is called "assigning a name to a socket" when a socket is created with socket, it exists in a when a socket is created with socket, it exists in a

name space (address family) but has no name assignedname space (address family) but has no name assigned3.3. listen()listen()

To accept connections, a socket is first created with To accept connections, a socket is first created with socket(), a willingness to accept incoming socket(), a willingness to accept incoming connections and a queue limit for incoming connections connections and a queue limit for incoming connections are specified with listen, and then the connections are are specified with listen, and then the connections are accepted with accept().accepted with accept().

4.4. repeat forever:repeat forever:1.1. accept()accept()2.2. fork() a child process that performs reads and/or writes fork() a child process that performs reads and/or writes

as per ordinary file.as per ordinary file.

Page 37: 2.3 InterProcess Communication (IPC)

int accept ( int s, struct sockaddr* int accept ( int s, struct sockaddr* addr, socklen_t* addrlen );addr, socklen_t* addrlen );

► It . . .It . . .1.1. extracts the first connection request on the extracts the first connection request on the

queue of pending connections,queue of pending connections,2.2. creates a new connected socket with mostly creates a new connected socket with mostly

the same properties as s,the same properties as s,3.3. and allocates a new file descriptor for the and allocates a new file descriptor for the

socket, which is returned.socket, which is returned.►The newly created socket is no longer in the The newly created socket is no longer in the

listening state.listening state.►The original socket s is unaffected by this The original socket s is unaffected by this

call.call.

Page 38: 2.3 InterProcess Communication (IPC)

/**/** * \file server2.cpp* \file server2.cpp * \author george j. grevera* \author george j. grevera * \brief A simple server in the internet domain using TCP. Runs on* \brief A simple server in the internet domain using TCP. Runs on * polaris (but not on scott).* polaris (but not on scott). * To compile: g++ -o server2.exe server2.cpp -lsocket* To compile: g++ -o server2.exe server2.cpp -lsocket */*/#include <assert.h>#include <assert.h>#include <netinet/in.h>#include <netinet/in.h>#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>#include <string.h>#include <string.h>#include <sys/socket.h>#include <sys/socket.h>#include <unistd.h>#include <unistd.h>

static const int Port = 8090;static const int Port = 8090;static const bool Verbose = true;static const bool Verbose = true;//----------------------------------------------------------------------//----------------------------------------------------------------------int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) {

//create an endpoint for communication//create an endpoint for communication if (Verbose) puts( "socket()" );if (Verbose) puts( "socket()" ); int sockfd = socket( AF_INET, SOCK_STREAM, 0 );int sockfd = socket( AF_INET, SOCK_STREAM, 0 ); assert( sockfd != -1 );assert( sockfd != -1 );……

Sockets – server-Sockets – server-sideside

Page 39: 2.3 InterProcess Communication (IPC)

…… //assign a name to the socket//assign a name to the socket struct sockaddr_in serv_addr;struct sockaddr_in serv_addr; memset( &serv_addr, 0, sizeof(serv_addr) );memset( &serv_addr, 0, sizeof(serv_addr) ); serv_addr.sin_family = AF_INET;serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY;serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons( Port );serv_addr.sin_port = htons( Port ); if (Verbose) printf( "bind() port %d. \n", Port );if (Verbose) printf( "bind() port %d. \n", Port ); int ret = bind( sockfd, (struct sockaddr*)&serv_addr, int ret = bind( sockfd, (struct sockaddr*)&serv_addr,

sizeof(serv_addr) );sizeof(serv_addr) ); assert( ret != -1 );assert( ret != -1 );……

Sockets – server-Sockets – server-sideside

Page 40: 2.3 InterProcess Communication (IPC)

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

Sockets – server-Sockets – server-sideside

Page 41: 2.3 InterProcess Communication (IPC)

…… for ( ; ; ) {for ( ; ; ) { //extract the first connection request on the queue of//extract the first connection request on the queue of // pending connections, create a new connected socket with// pending connections, create a new connected socket with // mostly the same properties as s, and allocate a new file// mostly the same properties as s, and allocate a new file // descriptor for the socket, which is returned// descriptor for the socket, which is returned if (Verbose) puts( "parent: accept()" );if (Verbose) puts( "parent: accept()" ); struct sockaddr_in cli_addr;struct sockaddr_in cli_addr; socklen_t clilen = sizeof( cli_addr );socklen_t clilen = sizeof( cli_addr ); int newsockfd = accept( sockfd, (struct sockaddr*)&cli_addr, &clilen );int newsockfd = accept( sockfd, (struct sockaddr*)&cli_addr, &clilen ); assert( newsockfd != -1 );assert( newsockfd != -1 );

if (Verbose) puts( "parent: fork()" );if (Verbose) puts( "parent: fork()" ); int pid = fork();int pid = fork(); if (pid==0) {if (pid==0) { <child process code here><child process code here> }} close( newsockfd ); //back in parentclose( newsockfd ); //back in parent }}

return 0;return 0;}}//----------------------------------------------------------------------//----------------------------------------------------------------------

Sockets – server-Sockets – server-sideside

if (Verbose) puts( "child: begin after fork()" );if (Verbose) puts( "child: begin after fork()" ); close( sockfd );close( sockfd );

char buffer[ 256 ];char buffer[ 256 ]; memset( buffer, 0, sizeof(buffer) );memset( buffer, 0, sizeof(buffer) ); if (Verbose) puts( "child: read()" );if (Verbose) puts( "child: read()" ); int n = read( newsockfd, buffer, sizeof(buffer)-1 );int n = read( newsockfd, buffer, sizeof(buffer)-1 ); assert( n != -1 );assert( n != -1 );

if (Verbose) {if (Verbose) { printf( "child: here is the message: %s \n", buffer );printf( "child: here is the message: %s \n", buffer ); puts( "child: write()" );puts( "child: write()" ); }} char* msg = "I got your message.";char* msg = "I got your message."; n = write( newsockfd, msg, strlen(msg)+1 ); //+1 to n = write( newsockfd, msg, strlen(msg)+1 ); //+1 to

include \0include \0 assert( n != -1 );assert( n != -1 );

close( newsockfd );close( newsockfd ); if (Verbose) puts( "child: end" );if (Verbose) puts( "child: end" ); exit( 0 ); //end childexit( 0 ); //end child

Page 42: 2.3 InterProcess Communication (IPC)

Sockets – server-side Sockets – server-side (complete code)(complete code)

/**/** * \file server2.cpp* \file server2.cpp * \author george j. grevera* \author george j. grevera * \brief A simple server in the internet domain using TCP. Runs on* \brief A simple server in the internet domain using TCP. Runs on * polaris (but not on scott).* polaris (but not on scott). * To compile: g++ -o server2.exe server2.cpp -lsocket* To compile: g++ -o server2.exe server2.cpp -lsocket */*/#include <assert.h>#include <assert.h>#include <netinet/in.h>#include <netinet/in.h>#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>#include <string.h>#include <string.h>#include <sys/socket.h>#include <sys/socket.h>#include <unistd.h>#include <unistd.h>

static const int Port = 8090;static const int Port = 8090;static const bool Verbose = true;static const bool Verbose = true;//----------------------------------------------------------------------//----------------------------------------------------------------------int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) {

//create an endpoint for communication//create an endpoint for communication if (Verbose) puts( "socket()" );if (Verbose) puts( "socket()" ); int sockfd = socket( AF_INET, SOCK_STREAM, 0 );int sockfd = socket( AF_INET, SOCK_STREAM, 0 ); assert( sockfd != -1 );assert( sockfd != -1 );

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

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

for ( ; ; ) {for ( ; ; ) { //extract the first connection request on the queue of//extract the first connection request on the queue of // pending connections, create a new connected socket with// pending connections, create a new connected socket with // mostly the same properties as s, and allocate a new file// mostly the same properties as s, and allocate a new file // descriptor for the socket, which is returned// descriptor for the socket, which is returned if (Verbose) puts( "parent: accept()" );if (Verbose) puts( "parent: accept()" ); struct sockaddr_in cli_addr;struct sockaddr_in cli_addr; socklen_t clilen = sizeof( cli_addr );socklen_t clilen = sizeof( cli_addr ); int newsockfd = accept( sockfd, (struct sockaddr*)&cli_addr, &clilen );int newsockfd = accept( sockfd, (struct sockaddr*)&cli_addr, &clilen ); assert( newsockfd != -1 );assert( newsockfd != -1 );

if (Verbose) puts( "parent: fork()" );if (Verbose) puts( "parent: fork()" ); int pid = fork();int pid = fork(); if (pid==0) {if (pid==0) { if (Verbose) puts( "child: begin after fork()" );if (Verbose) puts( "child: begin after fork()" ); close( sockfd );close( sockfd );

char buffer[ 256 ];char buffer[ 256 ]; memset( buffer, 0, sizeof(buffer) );memset( buffer, 0, sizeof(buffer) ); if (Verbose) puts( "child: read()" );if (Verbose) puts( "child: read()" ); int n = read( newsockfd, buffer, sizeof(buffer)-1 );int n = read( newsockfd, buffer, sizeof(buffer)-1 ); assert( n != -1 );assert( n != -1 );

if (Verbose) {if (Verbose) { printf( "child: here is the message: %s \n", buffer );printf( "child: here is the message: %s \n", buffer ); puts( "child: write()" );puts( "child: write()" ); }} char* msg = "I got your message.";char* msg = "I got your message."; n = write( newsockfd, msg, strlen(msg)+1 ); //+1 to include \0n = write( newsockfd, msg, strlen(msg)+1 ); //+1 to include \0 assert( n != -1 );assert( n != -1 );

close( newsockfd );close( newsockfd ); if (Verbose) puts( "child: end" );if (Verbose) puts( "child: end" ); exit( 0 );exit( 0 ); }} close( newsockfd );close( newsockfd ); }}

return 0;return 0;}}//----------------------------------------------------------------------//----------------------------------------------------------------------

Page 43: 2.3 InterProcess Communication (IPC)

DemoDemo►Run server on one system (brunel).Run server on one system (brunel).

./server2.exe./server2.exe Waits for a message from the client, and Waits for a message from the client, and

then responds.then responds.►Run client (on same or different system).Run client (on same or different system).

./client.exe brunel 8090./client.exe brunel 8090 Prompts for a message, sends message to Prompts for a message, sends message to

server, and then outputs response message server, and then outputs response message from server.from server.

Page 44: 2.3 InterProcess Communication (IPC)

Message QueuesMessage Queues

Page 45: 2.3 InterProcess Communication (IPC)

Message queues (Unix/Linux)Message queues (Unix/Linux)#include <sys/types.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/ipc.h>#include <sys/msg.h>#include <sys/msg.h>

► MSGMAX (Linux) defines the max length of a message MSGMAX (Linux) defines the max length of a message (~8K).(~8K).

► Define your message(s).Define your message(s). You may define many different messages of different lengths.You may define many different messages of different lengths.

struct myMessage {struct myMessage {long mtype;long mtype; //message type//message type…… //body of message (you decide)//body of message (you decide)

};};

Page 46: 2.3 InterProcess Communication (IPC)

Message queues (Unix/Linux)Message queues (Unix/Linux)►msgget - begin accessing (and create if msgget - begin accessing (and create if

necessary) a message queuenecessary) a message queueint msgget ( key_t key, int msgflg );int msgget ( key_t key, int msgflg );

►msgsnd - send (enqueue) a messagemsgsnd - send (enqueue) a messageint msgsnd ( int msqid, struct msgbuf* msgp,int msgsnd ( int msqid, struct msgbuf* msgp,

size_t msgsz, int msgflg );size_t msgsz, int msgflg );►msgrcv - receive (dequeue) a messagemsgrcv - receive (dequeue) a message

ssize_t msgrcv ( int msqid, struct msgbuf* msgp,ssize_t msgrcv ( int msqid, struct msgbuf* msgp,size_t msgsz, long msgtyp, int msgflg );size_t msgsz, long msgtyp, int msgflg );

►msgctl - misc. message queue controlmsgctl - misc. message queue control

Page 47: 2.3 InterProcess Communication (IPC)

ExampleExample//file: m.h//file: m.h

//declare the message structure//declare the message structuretypedef struct {typedef struct { enum { mTypeA, mTypeB, mTypeC };enum { mTypeA, mTypeB, mTypeC }; long mtype;long mtype; char mtext[ 256 ];char mtext[ 256 ];} message_buf;} message_buf;

#define KEY 1234#define KEY 1234

Page 48: 2.3 InterProcess Communication (IPC)

Example (sender)Example (sender)//file: mtx.cpp//file: mtx.cpp

#include <sys/types.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/ipc.h>#include <sys/msg.h>#include <sys/msg.h>#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>#include <string.h>#include <string.h>

#include "m.h"#include "m.h"

int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { // Get the message queue id for the "name" 1234, which // Get the message queue id for the "name" 1234, which

was created bywas created by // the server.// the server. key_t key = KEY;key_t key = KEY; int msgflg = IPC_CREAT | 0666;int msgflg = IPC_CREAT | 0666; fprintf( stderr, "\nmsgget: Calling msgget(%#lx,%#o) \n", fprintf( stderr, "\nmsgget: Calling msgget(%#lx,%#o) \n",

key, msgflg );key, msgflg ); int msqid;int msqid; if ((msqid = msgget(key, msgflg)) < 0) {if ((msqid = msgget(key, msgflg)) < 0) { perror( "msgget" );perror( "msgget" ); exit( 1 );exit( 1 ); }}

fprintf( stderr, "msgget: msgget succeeded: msqid = %d \n", fprintf( stderr, "msgget: msgget succeeded: msqid = %d \n", msqid );msqid );

// We'll send message type B// We'll send message type B message_buf sbuf;message_buf sbuf; sbuf.mtype = sbuf.mTypeB;sbuf.mtype = sbuf.mTypeB; strcpy( sbuf.mtext, "Did you get this?" );strcpy( sbuf.mtext, "Did you get this?" ); //size_t buf_length = strlen(sbuf.mtext) + 1 ;//size_t buf_length = strlen(sbuf.mtext) + 1 ; size_t buf_length = sizeof( message_buf );size_t buf_length = sizeof( message_buf );

// Send a message.// Send a message. if (msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT) < 0)if (msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT) < 0) {{ printf( "%d, %d, %s, %d\n", msqid, sbuf.mtype, printf( "%d, %d, %s, %d\n", msqid, sbuf.mtype,

sbuf.mtext, buf_length );sbuf.mtext, buf_length ); perror( "msgsnd" );perror( "msgsnd" ); exit( 1 );exit( 1 ); }} printf( "Message: \"%s\" Sent \n", sbuf.mtext );printf( "Message: \"%s\" Sent \n", sbuf.mtext );

return 0;return 0;}}

Page 49: 2.3 InterProcess Communication (IPC)

Example (receiver)Example (receiver)//file mrx.cpp//file mrx.cpp

#include <sys/types.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/ipc.h>#include <sys/msg.h>#include <sys/msg.h>#include <stdio.h>#include <stdio.h>#include <stdlib.h>#include <stdlib.h>

#include "m.h"#include "m.h"

int main ( int argc, char* argv[] ) {int main ( int argc, char* argv[] ) { // Get the message queue id for the "name" // Get the message queue id for the "name"

KEY, which was created byKEY, which was created by // the server.// the server. int msqid = msgget( KEY, 0666 );int msqid = msgget( KEY, 0666 ); if (msqid < 0) {if (msqid < 0) { perror( "msgget" );perror( "msgget" ); exit( 1 );exit( 1 ); }}

// Receive an answer of message type B.// Receive an answer of message type B. message_buf rbuf;message_buf rbuf; if (msgrcv(msqid, &rbuf, sizeof(rbuf), 0, 0) if (msgrcv(msqid, &rbuf, sizeof(rbuf), 0, 0)

< 0)< 0) {{ perror( "msgrcv" );perror( "msgrcv" ); exit( 1 );exit( 1 ); }}

// Print the answer.// Print the answer. printf( "%d %s \n", rbuf.mtype, printf( "%d %s \n", rbuf.mtype,

rbuf.mtext );rbuf.mtext ); exit( 0 );exit( 0 );}}

Page 50: 2.3 InterProcess Communication (IPC)

Message queues (Windows)Message queues (Windows)► Call MQOpenQueue to open the queue with send access.Call MQOpenQueue to open the queue with send access.

► Call MQSendMessage to send the message.Call MQSendMessage to send the message.

► The MQReceiveMessage function allows you to read The MQReceiveMessage function allows you to read messages . When reading messages, you can either peek messages . When reading messages, you can either peek at (not removing them) or retrieve the messages (removing at (not removing them) or retrieve the messages (removing them) in the queue. Messages can be read either them) in the queue. Messages can be read either synchronously, asynchronously, or through a transaction.synchronously, asynchronously, or through a transaction.

► Call MQCloseQueue to close the opened queue and free Call MQCloseQueue to close the opened queue and free resources.resources.

Page 51: 2.3 InterProcess Communication (IPC)

Demo (Unix)Demo (Unix)►mtx.exemtx.exe

Creates queue (if necessary, so run first).Creates queue (if necessary, so run first). Queues up one message.Queues up one message.

►mrx.exemrx.exe Dequeues a message (waits, otherwise).Dequeues a message (waits, otherwise).

Page 52: 2.3 InterProcess Communication (IPC)

Other IPC Other IPC MechanismsMechanisms

Page 53: 2.3 InterProcess Communication (IPC)

Other IPC mechanisms:Other IPC mechanisms:►MonitorsMonitors

A collection of A collection of procedures, variables, procedures, variables, and data structures that and data structures that are all grouped together are all grouped together in a special kind of in a special kind of module or package.module or package.

Only one process can be Only one process can be active in a monitor at any active in a monitor at any instant.instant.

Page 54: 2.3 InterProcess Communication (IPC)

Monitors and the (bounded) Monitors and the (bounded) producer-consumer problemproducer-consumer problem

Page 55: 2.3 InterProcess Communication (IPC)

Where do we see monitors?Where do we see monitors?► ““The Java programming language provides The Java programming language provides

two basic synchronization idioms: two basic synchronization idioms: synchronized methods and synchronized synchronized methods and synchronized statements.”statements.”- from - from

http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

Page 56: 2.3 InterProcess Communication (IPC)

Where do we see monitors?Where do we see monitors?► ““Synchronization is built around an internal Synchronization is built around an internal

entity known as the intrinsic lock or monitor entity known as the intrinsic lock or monitor lock. (The API specification often refers to lock. (The API specification often refers to this entity simply as a "monitor.")”this entity simply as a "monitor.")”- from - from

http://download.oracle.com/javase/tutorial/essential/concurrency/locksync.html

Page 57: 2.3 InterProcess Communication (IPC)

Java support . . .Java support . . .1.1. synchronized methodssynchronized methods

2.2. synchronized statements (blocks)synchronized statements (blocks)

Page 58: 2.3 InterProcess Communication (IPC)

SYNCHRONIZED METHODSSYNCHRONIZED METHODS

Page 59: 2.3 InterProcess Communication (IPC)

Synchronized methodsSynchronized methods► To make a method synchronized, simply add the synchronized keyword to its To make a method synchronized, simply add the synchronized keyword to its

declaration:declaration:public class SynchronizedCounter {public class SynchronizedCounter { private int c = 0;private int c = 0; public synchronized void increment ( )public synchronized void increment ( ) { c++; }{ c++; } public synchronized void decrement ( )public synchronized void decrement ( ) { c--; }{ c--; } public synchronized int value ( )public synchronized int value ( ) { return c; }{ return c; }}}

► If If countcount is an instance of SynchronizedCounter, then making these methods is an instance of SynchronizedCounter, then making these methods synchronized has two effects:synchronized has two effects:

1.1. First, it is not possible for two invocations of synchronized methods on the same object to First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.the first thread is done with the object.

2.2. Second, when a synchronized method exits, it automatically establishes a Second, when a synchronized method exits, it automatically establishes a happens-before happens-before relationshiprelationship with any subsequent invocation of a synchronized method for the same object. with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.This guarantees that changes to the state of the object are visible to all threads.

- from http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html- from http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

Page 60: 2.3 InterProcess Communication (IPC)

Locks in synchronized Locks in synchronized methodsmethods

► When a thread invokes a synchronized method, it When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that automatically acquires the intrinsic lock for that method's object and releases it when the method method's object and releases it when the method returns.returns. The lock release occurs even if the return was caused by an The lock release occurs even if the return was caused by an

uncaught exception.uncaught exception.

- from - from http://download.oracle.com/javase/tutorial/essential/concurrency/lockshttp://download.oracle.com/javase/tutorial/essential/concurrency/locksync.htmlync.html

Page 61: 2.3 InterProcess Communication (IPC)

Locks in synchronized Locks in synchronized methodsmethods

► You might wonder what happens when a static You might wonder what happens when a static synchronized method is invoked, since a static method is synchronized method is invoked, since a static method is associated with a class, not an object.associated with a class, not an object.

► In this case, the thread acquires the intrinsic lock for the In this case, the thread acquires the intrinsic lock for the Class object associated with the class.Class object associated with the class.

► Thus access to class's static fields is controlled by a lock Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class.that's distinct from the lock for any instance of the class.

- from - from http://download.oracle.com/javase/tutorial/essential/concurrency/locksync.htmlhttp://download.oracle.com/javase/tutorial/essential/concurrency/locksync.html

Page 62: 2.3 InterProcess Communication (IPC)

SYNCHRONIZED SYNCHRONIZED STATEMENTSSTATEMENTS

Page 63: 2.3 InterProcess Communication (IPC)

Synchronized statementsSynchronized statementspublic void addName ( String public void addName ( String

name )name ){{ synchronized (this) {synchronized (this) { lastName = name;lastName = name; nameCount++;nameCount++; }} nameList.add( name );nameList.add( name );}}

public class MsLunch {public class MsLunch { private long c1 = 0;private long c1 = 0; private long c2 = 0;private long c2 = 0; private Object lock1 = new Object();private Object lock1 = new Object(); private Object lock2 = new Object();private Object lock2 = new Object(); public void inc1 ( ) {public void inc1 ( ) { synchronized (lock1) {synchronized (lock1) { c1++;c1++; }} }} public void inc2 ( ) {public void inc2 ( ) { synchronized (lock2) {synchronized (lock2) { c2++;c2++; }} }}}}

Single lock taken out on this entire object (instance).

Locks taken out on two different objects for finer control.

Page 64: 2.3 InterProcess Communication (IPC)

Other IPC mechanisms:Other IPC mechanisms:►Message passing (MPI)Message passing (MPI)►Barriers (also implemented in MPI and Barriers (also implemented in MPI and

the pthread library)the pthread library)