![](https://csdnimg.cn/release/download_crawler_static/4805518/bg13.jpg)
from its initial routine, as it does here, the thread terminates. Normally, Pthreads would hold the
thread's resources so that another thread could later determine that it had exited and retrieve a final
result. Because the thread detached itself, none of that is necessary.
alarm_thread.c part 2 alarm_thread
The main program of alarm thread.c is much the same as the other two variants. It loops,
reading and interpreting command lines as long as it can read from stdin.
12-25 In this variation, main allocates heap storage (alarm_t) for each alarm command. The alarm
time and message are stored in this structure, so each thread can be given the appropriate
information. If the sscanf call fails to "parse" a correct command, the heap storage is freed.
12-26 An alarm thread is created, running function alarm_thread, with the alarm data (alarm_t) as
the thread's argument.
alarm_thread.c part 3 main
1.5.4 Summary
A good way to start thinking about threads is to compare the two asynchronous versions of
the alarm program. First, in the fork version, each alarm has an independent address space, copied
from the main program. That means we can put the seconds and message values into local
variables--once the child has been created (when fork returns), the parent can change the values
without affecting the alarm. In the threaded version, on the other hand, all threads share the same
address space--so we call malloc to create a new structure for each alarm, which is passed to the
new thread. The extra bookkeeping required introduces a little complexity into the threaded
version.
In the version using fork, the main program needs to tell the kernel to free resources used by
each child process it creates, by calling waitpid or some other member of the wait "family." The
alarm_fork.c program, for example, calls waitpid in a loop after each command, to collect all child
processes that have completed. You do not need to wait for a thread unless you need the thread's
return value--in alarm_thread.c, for example, each alarm thread detaches itself (at line 6, part 2) so
that the resources held by the thread will be returned immediately when it terminates.
In the threaded version, the "primary activities" (sleeping and printing the message) must be
coded in a separate routine. In alarm.c and alarm_fork.c, those activities were performed without a
call. In simple cases such as our alarm program, it is often easier to understand the program with
all code in one place, so that might seem like an advantage for alarm_fork. c. In more complicated
programs, though, it is rare that a program's "primary activities" are so simple that they can be
performed in a single routine without resulting in total confusion.
In a real alarm program, you wouldn't want to create a process for each alarm. You might
easily have hundreds of alarms active, and the system probably wouldn't let you create that many
processes. On the other hand, you probably can create hundreds of threads within a process. While
there is no real need to maintain a stack and thread context for each alarm request, it is a perfectly
viable design.
A more sophisticated version of alarm_thread.c might use only two threads: one to read input
from the user, and another to wait for expiration of the next alarm--I'll show that version later,