Instructor's Manual for

M.B. Feldman and E.B. Koffman, Ada 95 Problem Solving and Program Design, 3rd edition. Copyright 1999, Addison-Wesley Publishing Company. All Rights Reserved

Questions and comments to mfeldman@seas.gwu.edu


Chapter 17 Introduction to Concurrent Programming

last revised March 1999.

Chapter Objectives

The student will

  1. learn about general concepts of concurrent programming
  2. learn how to manipulate task types and objects
  3. learn how to manipulate protected types and objects

New Terms

Section 17.1

concurrent program

simulation

readers-writers problem

mutual exclusion

Section 17.2

task specification

task body

task activation

cooperative multitasking

task entry

"start button"

ACCEPT statement

Section 17.3

protected type

protected operation

multiwindow program

General Suggestions

This chapter is intended to whet the student's appetite for further study of concurrent programming. Space in this book did not permit anything like a full discussion of the topic. Indeed, we have omitted all discussion of the SELECT statement, which provides much of the power in intertask synchronization and communication.

Section 17.1

Spend some time on a general discussion of concurrent programming. We view concurrency as a very general subject, of which parallelism is a special case. Students who read the trade press sometimes have a narrow view of concurrency in which efficiency (read: the program is, in some sense, faster) is a dominant motive. While it is often useful to distribute a program's functionality over multiple processors for performance and others reasons, concurrency ought, in fact, to be seen as an abstraction mechanism which may have some performance benefits under some circumstances.

Concurrency as an abstraction tool gives us the ability to say, clearly, that certain of our constructs may be executed simultaneously. Concurrency constructs in a programming language give us the ability to make these statements in a platform-independent manner. There is no fundamental reason why using these constructs should make a program less efficient than using operating system calls to specify the concurrency, and using them makes programs clearer and therefore, one hopes, more reliable.

Section 17.2

This section gives four short programs that illustrate some of the syntax and basic behavior of Ada tasks: implicit activation, likely run-till-blocked scheduling, and so on. You and the students definitely should run these programs to assess their behavior with your compiler's runtime library.

If you are familiar with Ada 83 tasking but not the Ada 95 version, you may be surprised that the core standard is silent on the question of task dispatching, all discussion of this as well as of priorities having been moved to the Real-Time Systems Annex. In this book we discuss only tasking as implemented in the core language, thus priorities are not discussed.

Since, in our discussion, all tasks have the same priority, there is no reason to expect one task to have a greater "right" to the processor than others. For equal-priority tasks, neither time-slicing nor preemption is required. Students, having heard about "preemptive multitasking," may not understand why time-slicing and preemption are not required for equal-priority tasks. Explain that there is a good bit of overhead associated with this. The most portable style for tasks is therefore a cooperative style, in which each task executes a DELAY statement from time to time, typically in each iteration of its main loop. In this manner, tasks yield politely to one another.

Section 17.3

The protected type is a new feature of Ada 95, designed to provide a simple form of mutual-exclusion protection on a data structure. In Ada 83 this was accomplished with an additional task to manage the data structure. Such a task typically exported Read and Write entries; the overhead of the associated rendezvous and context switches was seen to be excessive, and also unnecessary for the simple mutual-exclusion situation. Protected types are very similar to monitors; protected operations can be executed in the caller's control thread, thus without a context switch.

The two programs in this section are designed to show the need for protected types.

Section 17.4

This section presents a "fun" and esy-to-implement application of tasks, namely, the creation of an entire family of "drunken spiders". Program 17.7 shows how to create a spider task type, whose code is remarkably simple and straightforward. Program 17.9 shows that task objects can be array elements, which may come as a surprise to students unaccustomed to the notion of a program as a data structure. It is fun to watch all the spiders squiggling around on the screen, bouncing off each other and the walls.