CSI 402 - Systems Programming - Handout 15.4 An Example For Select System Call
CSI 402 - Systems Programming - Handout 15.4 An Example For Select System Call
4
An Example for select System Call
Note: This example, taken from pages 166167 of the text by Haviland et al., shows how select
system call can be used by a parent process to monitor the read-ends of pipes with three children and
also stdin.
The parent process creates three pipes and three children. Each child sends messages to the parent
through a pipe. The parent then waits in a loop, using the select system call to check the read-ends
of the three pipes as well as stdin. Each child writes two messages and then exits. The parent waits
for all the children to exit. When this program is executed, the messages sent by children and the
characters typed by a user from the keyboard will all be interleaved.
#include
#include
#include
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<errno.h>
<fcntl.h>
<unistd.h>
<sys/time.h>
<sys/wait.h>
#define
#define
#define
MSGSIZE
NPIPES
NDESC
6
3
2
0:
/* Child process. */
child(pfd[i]);
} /* End of switch. */
}
parent(pfd); /* Parent will monitor all the three pipes and stdin. */
return 0;
} /* End of main. */
*/
*/
/* Parent calls select without timeout. So, parent will block until */
/* an event occurs.
*/
/* We need to remember the master bit mask since select will change the mask. */
tset = master;
nfd = p[NPIPES-1][0]+1; /* The no. of file descriptors must include stdin. */
while (select(nfd, &tset, NULL, NULL, NULL) > 0) {
/* Check if stdin has any data and print it. */
if (FD_ISSET(STDIN_FILENO, &tset)) {
printf("From stdin: "); read(STDIN_FILENO, &tc,1);
printf("%c\n", tc);
}
/* Check if any of the pipes has data and print the data. */
for (i = 0; i < NPIPES; i++){
if (FD_ISSET(p[i][0], &tset)) {
if (read(p[i][0], buf, MSGSIZE) > 0)
printf("Message from Child %d: %s\n", i, buf);
}
} /* End of for. */
/* The server will return to the main program if all children have exited. */
if (waitpid(-1, NULL, WNOHANG) == -1)
return 0;
/* Otherwise, we need to restore the master bit mask and call select again. */
tset = master;
} /* End of while. */
return 0;
} /* End of parent. */
NUM_MSG
DIVISOR
2
4
/* Code for each child process. Each child process writes two messages */
/* with a different waiting time between the messages and quits.
*/
int count;
/* Close the read-end of the pipe. */
if (close(p[0]) == -1) { /* Failed to close read end of pipe. */
fprintf(stderr, "Child: Couldnt close read end of pipe.\n");
exit(1);
}
/* Send messages through the pipe. */
for (count = 0; count < NUM_MSG; count++) {
write(p[1], msg1, MSGSIZE);
sleep(getpid() % DIVISOR);
}
/* Send the final message. */
write(p[1], msg2, MSGSIZE);
exit(0);
} /* End of child. */
Sample output: After starting the program, the user typed the character x followed by \n.
Notice that both of these characters are written to the output along with the messages from Children
0, 1 and 2.
Message from Child
Message from Child
Message from Child
Message from Child
From stdin: x
From stdin:
0:
1:
2:
0:
hello
hello
hello
hello
Message
Message
Message
Message
Message
1:
0:
2:
1:
2:
hello
bye!!
hello
bye!!
bye!!
from
from
from
from
from
Child
Child
Child
Child
Child