IPC Programming
Faculty of Computer Science and Engineering
Ho chi Minh city University of Technology
SinhVienZone.com
/>
Introduction
Inter-Process Communication
Sending messages between processes
Sharing information between processes
Synchronization
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
IPC
Communication
Transferring message
Sharing information
Mechanisms:
Pipe
Signal
Message queue
Shared memory
Socket
RPC/RMI
SinhVienZone.com
Synchronization
Solving confliction
Processing order
Mechanisms:
Lock file
Semaphore
Mutex (pthread)
/>Faculty of Computer Science and Engineering - HCMUT
IPC Programming
Pipe
Signal
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
Pipe
Processes communicate to each other using pipe through
FIFO mechanism
P0
write
SinhVienZone.com
read
/>Faculty of Computer Science and Engineering - HCMUT
P1
Pipe operations
Write:
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count)
Read:
#include <unistd.h>
ssize_t read(int fd, const void *buf, size_t count)
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
Pipe types
Unnamed pipe
Local
Used in processes having parent-child relation
Named pipe (FIFO)
Global
Used by any processes
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
Unnamed pipe
#include <unistd.h>
int pipe(int filedes[2]);
Return value:
0: if successful, two file descriptors filedes[0], filedes[1]
will be stored in filedes
-1: if error and error code is stored in external errno
variable
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
Unnamed pipe
filedes[1]
P0
P1
filedes[0]
Unidirectional/half-duplex
filedes[0] is only used to read
filedes[1] is only used to write
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<unistd.h>
<string.h>
int main() {
int fp[2];
char s1[BUFSIZ], s2[BUFSIZ];
pipe(fp);
Compile and execute
$gcc unpipe.c -o unpipe
$./unpipe
Input: I Love Penguin
From pipe> I Love
Penguin
$
if (fork()==0) { /* Child Write */
printf("\nInput: ");
fgets(s1,BUFSIZ,stdin);
s1[strlen(s1)]=0;
close(fp[0]);
write(fp[1],s1,strlen(s1)+1);
} else {
/*Parent Read*/
close(fp[1]);
read(fp[0],s2,BUFSIZ);
printf("\nFrom pipe> %s\n", s2);
}
return 0;
}
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
File redirecting
dup()
dup2()
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
dup()
#include <unistd.h>
int dup(int oldfd);
stdin
0
stdout
stderr
available
stdin
0
1
stdout
1
2
stderr
2
dup(1)
3
4
SinhVienZone.com
3
available
4
/>Faculty of Computer Science and Engineering - HCMUT
dup2()
#include <unistd.h>
int dup2(int oldfd, int newfd);
stdin
0
stdout
stderr
available
stdin
0
1
stdout
1
2
stderr
2
3
4
SinhVienZone.com
dup2(1,4)
available
3
4
/>Faculty of Computer Science and Engineering - HCMUT
Example
// ls -l > output.txt
#include <unistd.h>
int main() {
int fd=open(“output.txt”);
close(1);
dup(fd);
system(“ls –l”);
close (fd);
return 0;
}
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
Redirecting with pipe
Using file redirecting technique to implement pipe
$ ps -ef | grep a01 | sort
ps -ef
cmd1
SinhVienZone.com
|
grep a01
|
cmd2
/>Faculty of Computer Science and Engineering - HCMUT
...
. . . cmdN
#include <unistd.h>
int main() {
// ps -ef | grep a01 | sort
int pipe1[2], pipe2[2];
pipe(pipe1);
if (fork()) { /* Parent */
pipe(pipe2);
if(fork()) { /* Parent */
close(0);
// Close standard input
dup(pipe2[0]); // standard input -> Read Pipe2
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execlp("/bin/sort", "sort", NULL);
}
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
else { /* Child 2 */
close(0);
// Close standard input
dup(pipe1[0]); // standard input -> Read Pipe1
close(1);
// Close standard output
dup(pipe2[1]); // standard output -> Write Pipe2
close(pipe1[0]); close(pipe1[1]);
close(pipe2[0]); close(pipe2[1]);
execlp("/bin/grep", "grep", “a01”,NULL);
}
} else { /* Child 1 */
close(1);
// Close standard output
dup(pipe1[1]); // standard output -> Write Pipe1
close(pipe1[0]); close(pipe1[1]);
execlp("/bin/ps", "ps", "-ef", NULL);
}
exit(0);
}
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
Named pipe
Similar to unnamed pipe
Notice:
Similar to a file on file system (directory entry, file
permission)
Can be used on any processes
Can be created from a command on shell (using mknod
command)
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
Create named pipe
System call
#include <sys/types.h>
#include <sys/stat.h>
int mknod(const char *path,mode_t mode,dev_t dev);
C/C++ library call
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
extern int errno;
Compile and execute
$gcc fifo.c -o fifo
$./fifo
Parent writes to FIFO1: Test1
Child reads from FIFO1: Test1
Child feedbacks on FIFO2: Test2
Feedback data from FIFO2: Test2
$
#define FIFO1 "/tmp/fifo.1"
#define FIFO2 "/tmp/fifo.2"
#define PERMS 0666
int main(){
char s1[BUFSIZ], s2[BUFSIZ];
int childpid, readfd, writefd;
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
if ((mknod(FIFO1, S_IFIFO | PERMS,
(errno!=EEXIST)) {
printf("can't create fifo1: %s",
exit(1);
}
if ((mknod(FIFO2, S_IFIFO | PERMS,
(errno!=EEXIST)) {
unlink(FIFO1);
printf("can't create fifo2: %s",
exit(1);
}
if ((childpid=fork())<0) {
printf("can't fork");
exit(1);
}
SinhVienZone.com
0)<0) &&
FIFO1);
0)<0) &&
FIFO2);
/>Faculty of Computer Science and Engineering - HCMUT
else if (childpid>0) { /* parent */
if ((writefd=open(FIFO1,1))<0)
perror("parent: can't open writefifo");
if ((readfd=open(FIFO2,0))<0)
perror("parent: can't open readfifo");
printf("\nParent writes to FIFO1: ");
gets(s1);
s1[strlen(s1)]=0;
write(writefd,s1,strlen(s1)+1);
read(readfd,s2,BUFSIZ);
printf("\nFeedback data from FIFO2: %s\n",s2);
while (wait((int*)0)!=childpid);
close(readfd);
close(writefd);
if (unlink(FIFO1)<0) perror("Can't unlink FIFO1");
if (unlink(FIFO2)<0) perror("Can't unlink FIFO2");
exit(0);
}
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
else { /* child */
if ((readfd=open(FIFO1,0))<0)
perror("child: can't open readfifo");
if ((writefd=open(FIFO2,1))<0)
perror("child: can't open writefifo");
read(readfd,s2,BUFSIZ);
printf("\nChild read from FIFO1: %s\n",s2);
printf("\nInput string from child to feedback: ");
gets(s1);
s1[strlen(s1)]=0;
write(writefd,s1,strlen(s1)+1);
close(readfd);
close(writefd);
exit(0);
}
}
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
IPC Programming
Pipe
Signal
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT
Signal
signals
(events)
Process
SinhVienZone.com
/>Faculty of Computer Science and Engineering - HCMUT