Книга: Programming with POSIX® Threads
1.5.2 A version using multiple processes
1.5.2 A version using multiple processes
There are lots of ways to make this program asynchronous; for example, you could run more than one copy of the program. One way to run multiple copies is to fork a child process for each command, as shown in alarm_fork.c. The new version is asynchronous—you can enter commands at any time, and they will be carried out independently. It isn't much more complicated than the original, which is nice.
27-37 The main difference between alarm.c and alarm_fork.c is that instead of calling sleep directly, it uses fork to create a new child process, which then calls sleep (and, eventually, printf) asynchronously, while the parent process continues.
42-46 The primary complication in this version is the need to "reap" any child processes that have terminated. If the program fails to do this, the system will save them all until the program terminates. The normal way to reap terminated child processes is to call one of the wait functions. In this case, we call waitpid, which allows the caller to specify the WNOHANG flag. The function will immediately reap one child process if any have terminated, or will immediately return with a process ID (pid) of 0. The parent process continues to reap terminated child processes until there are no more to reap. When the loop terminates, main loops back to line 13 to read a new command.
? alarm_fork.c
1 #include <sys/types.h>
2 #include <wait.h>
3 #include "errors.h"
5 int main (int argc, char *argv[])
6 {
7 int status;
8 char line[128];
9 int seconds;
10 pid_t pid;
11 char message[64]; 12
13 while (1) {
14 printf ("Alarm> " ) ;
15 if (fgets (line, sizeof (line), stdin) == NULL) exit (0);
16 if (strlen (line) <= 1) continue;
17
18 /*
19 * Parse input line into seconds (%d) and a message
20 * (%64[^n]), consisting of up to 64 characters
21 * separated from the seconds by whitespace.
22 */
23 if (sscanf (line, "%d %64[^n]",
24 &seconds, message) < 2) {
25 fprintf (stderr, "Bad commandn");
26 } else {
27 pid = fork ( );
28 if (pid == (pid_t)-l)
29 errno_abort ("Fork");
30 if (pid == (pid_t)0) {
31 /*
32 * In the child, wait and then print a message
33 */
34 sleep (seconds);
35 printf ("(%d) %sn", seconds, message);
36 exit (0);
37 } else {
38 /*
39 * In the parent, call waitpid() to collect children
40 * that have already terminated.
41 */
42 do {
43 pid = waitpid ((pid_t)-l, NULL, WNOHANG);
44 if (pid == (pid_t)-l)
45 errno_abort ("Wait for child");
46 } while (pid != (pid_t)0);
47 }
48 }
49 }
- 1.5 Asynchronous programming, by example
- 1.5.3 A version using multiple threads
- ODS version
- Caveats using NAT
- Using Double Quotes to Resolve Variables in Strings with Embedded Spaces
- Type Conversion
- Data Binding Using the GridView Control
- Using the kill Command to Control Processes
- Installing Using a Network
- Using X
- Using a Display Manager
- Starting X from the Console by Using startx