Transcript Slide 1

Operating Systems
Chapter 3
Interprocess
Communication (IPC)
Interprocess Communication (IPC)




I/O
Pipes
Shared memory
Message Passing
I/O System Calls




I/O operations made by descriptors
Descriptors are integer values represent indexes for
special tables that are handle by the OS kernel to
access the data – (a file can be a device also)
Every process has his own descriptors , saved in his
PDT – process descriptor table
By default , every process has 3 descriptors:
•
•
•
0 – stdin - keyboard
1 – stdout - screen
2 – stderr - screen
open

Open a file/device for read/write
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char* path,int oflag, /*mode_t mode */ …);


oflags – O_RDWR , O_WRONLY,O_RONLY
The function returns the file descriptor or -1 if
it fails.
close
Close the descriptor to the file
#include <unistd.h>
int close(int filedes)


return 0 on success and -1 when fail
dup
create a new descriptor to the same file with
the same attributes
 The new descriptor will be the first free index
in the PDT
#include <unistd.h>
int dup(int filedes);
 Returns the new descriptor or -1 when fail

read & write
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
size_t read(int filedes,void *buf,size_t nbytes);
size_t write(int filedes,const void *buf,size_t nbytes);
Pipes




FIFO data passing
Can use for synchronization
Implement via files by two descriptors (read ,
write)
Pipe types:
• Named pipe
• Unnamed pipes
Unnamed Pipes


Create by the pipe system call
Parent share the pipe with his children
Proc A
B Call to pipe()
Proc B
Proc D
Proc C
Proc E
Share the same pipes
Create pipe
#include <unistd.h>
int pipe(int filedes[2]);


On success : fildes[0] – descriptor for read
fildes[1] – descriptor for write
return value 0
On failure :
return value -1
Fildes[1]
Process
Fildes[0]
Pipe
Process
Example #1
int file_pipes[2];
Char some_data[] = “123”;
pipe(file_pipes) ;
fork_result = fork();
…
if (fork_result == 0) {
close(file_pipes[1]);
data_processed = read(file_pipes[0], buffer, BUFSIZ);
printf("Read %d bytes: %s\n", data_processed, buffer);
exit(EXIT_SUCCESS);
}
else {
close(files_pipes[0]);
data_processed = write(file_pipes[1], some_data,strlen(some_data)+1);
printf("Wrote %d bytes\n", data_processed);
}
Pipe properties




read will get EOF from a pipe which all the
write descriptors to it are closed.
If there are more that 1 process reading or
writing they must be synchronized .
When there is no place in the pipe, the writing
process is waiting
When there are no data in the pipe the
reading process is waiting (only if there are
writing descriptor to it).
Example #2 – son.c
/* son.c */
#include <stdio.h>
#include <unistd.h>
int main(int argc,char * argv[])
{
fprintf(stderr,"%s ",argv[1]);
write(1,"Bye !",6);
return 0;
}
Example #2 – father.c
/* father */
#include <stdio.h>
#include <unistd.h>
int main()
{
char string[10];
int index=0;
while(read(0,&(string[index++]),1)==1);
printf("%s\n",string);
return 0;
}
Example #2 – master.c
/* master.c */
#include<stdio.h>
#include<unistd.h>
int main(void)
{
static char* father_argv[] = {"father",NULL};
static char* son_argv[] = {"son","Good",NULL};
int my_pipe[2];
int status;
status = pipe(my_pipe);
if(status == -1){
printf("Unable to open pipe");
exit(-1);
}
status = fork();
}
if (status !=0 ){
/* father process */
close(0);
dup(my_pipe[0]);
close(my_pipe[0]);
close(my_pipe[1]);
execve("./father",father_argv,0);
fprintf(stderr,"fathers execve has failed");
}
else{
close(1);
dup(my_pipe[1]);
close(my_pipe[0]);
close(my_pipe[1]);
execve("./son",son_argv,0);
fprintf(stderr,"sons execve has faild");
}