thread.pdf

(90 KB) Pobierz
35
An Introduction to Programming
with Threads
by Andrew D. Birrell
January 6, 1989
digi tal
Systems Research Center
130 Lytton Avenue
Palo Alto, California 94301
An Introduction to Programming with Threads
Andrew D. Birrell
This paper provides an introduction to writing concurrent programs with “threads”. A threads
facility allows you to write programs with multiple simultaneous points of execution,
synchronizing through shared memory. The paper describes the basic thread and
synchronization primitives, then for each primitive provides a tutorial on how to use it. The
tutorial sections provide advice on the best ways to use the primitives, give warnings about
what can go wrong and offer hints about how to avoid these pitfalls. The paper is aimed at
experienced programmers who want to acquire practical expertise in writing concurrent
programs.
CR categories and Subject Descriptors: D.1.4 [Programming
Techniques]:
Concurrent
Programming; D.3.3 [Programming
Languages]:
Language Constructs—Concurrent
programming structures;
D.4.1 [Operating
Systems]:
Process Management
General Terms: Design, Languages, Performance
Additional Key Words and Phrases: Threads, Concurrency, Multi-processing, Synchronization
CONTENTS
Introduction...................................................................................................... 1
Why use concurrency?........................................................................................ 2
The design of a thread facility .............................................................................. 3
Using a Mutex: accessing shared data .................................................................... 7
Using a Condition variable: scheduling shared resources.......................................... 14
Using Fork: working in parallel......................................................................... 22
Using Alert: diverting the flow of control ............................................................ 27
Additional techniques ....................................................................................... 28
Building your program ..................................................................................... 30
Concluding remarks......................................................................................... 31
References...................................................................................................... 31
Appendix: other thread designs........................................................................... 33
Digital Equipment Corporation 1989
This work may not be copied or reproduced in whole or in part for any commercial
purpose. Permission to copy in whole or in part without payment of fee is granted for
non-profit educational and research purposes provided that all such whole or partial copies
include the following: a notice that such copying is by permission of the Systems
Research Center of Digital Equipment Corporation in Palo Alto, California; an
acknowledgement of the authors and individual contributors to the work; and all
applicable portions of the copyright notice. Copying, reproducing, or republishing for
any other purpose shall require a license with payment of fee to the Systems Research
Center. All rights reserved.
An Introduction to Programming with Threads
.
1
INTRODUCTION
Many experimental operating systems, and some commercial ones, have recently included
support for concurrent programming. The most popular mechanism for this is some
provision for allowing multiple lightweight “threads” within a single address space, used
from within a single program.
1
Programming with threads introduces new difficulties even for experienced
programmers. Concurrent programming has techniques and pitfalls that do not occur in
sequential programming. Many of the techniques are obvious, but some are obvious only
with hindsight. Some of the pitfalls are comfortable (for example, deadlock is a pleasant
sort of bug—your program stops with all the evidence intact), but some take the form of
insidious performance penalties.
The purpose of this paper is to give you an introduction to the programming
techniques that work well with threads, and to warn you about techniques or interactions
that work out badly. It should provide the experienced sequential programmer with enough
hints to be able to build a substantial multi-threaded program that works—correctly,
efficiently, and with a minimum of surprises.
A “thread” is a straightforward concept: a single sequential flow of control. In a high-
level language you normally program a thread using procedures, where the procedure calls
follow the traditional stack discipline. Within a single thread, there is at any instant a
single point of execution. The programmer need learn nothing new to use a single thread.
Having “multiple threads” in a program means that at any instant the program has
multiple points of execution, one in each of its threads. The programmer can mostly view
the threads as executing simultaneously, as if the computer were endowed with as many
processors as there are threads. The programmer is required to decide when and where to
create multiple threads, or to accept such decisions made for him by implementers of
existing library packages or runtime systems. Additionally, the programmer must
occasionally be aware that the computer might not in fact execute all his threads
simultaneously.
Having the threads execute within a “single address space” means that the computer’s
addressing hardware is configured so as to permit the threads to read and write the same
memory locations. In a high-level language, this usually corresponds to the fact that the
off-stack (global) variables are shared among all the threads of the program. Each thread
executes on a separate call stack with its own separate local variables. The programmer is
responsible for using the synchronization mechanisms of the thread facility to ensure that
the shared memory is accessed in a manner that will give the correct answer.
Thread facilities are always advertised as being “lightweight”. This means that thread
creation, existence, destruction and synchronization primitives are cheap enough that the
programmer will use them for all his concurrency needs.
Please be aware that I am presenting you with a selective, biased and idiosyncratic
collection of techniques. Selective, because an exhaustive survey would be premature, and
would be too exhausting to serve as an introduction—I will be discussing only the most
important thread primitives, omitting features such as per-thread context information.
Biased, because I present examples, problems and solutions in the context of one
1
Throughout this paper I use the word “process” only when I mean a single flow of control
associated one-to-one with an address space, since this now seems to be the most common
usage of that word.
Zgłoś jeśli naruszono regulamin