Proceedings
of the 6th International Python Conference
Concurrent Object-Oriented Programming
in Python
with ATOM
Michael Papathomas |
|
Anders Andersen1 |
Computing Department |
|
NORUT IT |
Lancaster University |
|
Tromsø Research Park |
Lancaster LA1 4YR, UK |
|
9005 Tromsø, Norway |
michael@comp.lancs.ac.uk |
|
aandersen@acm.org |
Object-oriented
mechanisms, such as classes and inheritance, and concurrency mechanisms, such
as threads and locks, provide two separate software structuring dimensions.
The development of concurrent object-oriented software requires both
dimensions to be taken into account simultaneously. Previous research has
identified that substantial effort is required by programmers to avoid clashes
in structuring software along these separate dimensions. This has led to the
design of concurrent object-oriented programming models that integrate
object-oriented features with concurrent execution and synchronization,
eliminating the need to consider two separate dimensions when developing
concurrent object-oriented software. Although several issues that have to be
addressed by such programming models have been identified, there is no consent
on a programming model that addresses all these issues simultaneously. In
addition, little experience has been gained from the use of proposals
addressing these issues. We have used Python to prototype and experiment with
the use of a novel concurrent object-oriented programming model called ATOM.
In this paper we present the model's main features and illustrate their use
for concurrent programming in Python. We also provide information on a free
prototype implementation of the model. Taking advantage of Python's
extensibility we were able to prototype the model without undergoing a lengthy
development effort and with no need to change the Python language or its
interpreter.
Object-oriented mechanisms, such as classes and
inheritance, and concurrency mechanisms, such as threads and locks, provide
two separate software structuring dimensions. The development of concurrent
object-oriented software requires both dimensions to be taken into account
simultaneously. Previous research has identified that substantial effort is
required by programmers to avoid clashes in structuring software along these
separate dimensions. This has led to the design of concurrent object-oriented
programming models that integrate object-oriented features with concurrent
execution and synchronization eliminating the need to consider two separate
dimensions when developing concurrent object-oriented software [1].
There has been substantial research on Concurrent Object-Oriented
Programming (COOP) models and several issues that have to be addressed by such
models have been identified. However, research in the area are concentrated on
the design of features that address particular issues in isolation and there
is no consent on a programming model that addresses all these issues
simultaneously. Furthermore, few languages incorporating the proposed features
are widely available and little experience is reported from their use.
In this paper we present a COOP model, ATOM, and show how it can be used
for concurrent programming in Python. ATOM incorporates a number of novel
features that aim to address simultaneously all issues identified by previous
research in concurrent object-oriented programming. ATOM has been incorporated
and implemented in Python and we have already used it in the development of
concurrent object-oriented software. Section 2
provides some background on concurrent object-oriented programming and the
issues that have to be addressed by COOP models. In section 3,
we present ATOM's main features. Section 4,
shows how ATOM can be used for concurrent object-oriented programs in Python.
In section 5,
we discuss how ATOM features address concurrent programming issues, the
benefits from the use of Python and our plans for future work. Finally, we
present our conclusions in section 6.
The purpose of COOP models is to
integrate in a single programming model object-oriented features, such as
classes and inheritance, and features that support concurrent execution and
synchronization. In this section we provide a brief overview of the work in
this area, the motivation behind such models and the issues they have to
address. There has been abundant literature on COOP so it is impossible to
present all the work in this paper. A more extensive survey of work in the
area can be found in [2].
In a concurrent program objects
are shared by concurrent threads. In this case the execution of their methods
needs to be synchronized in order to provide mutually exclusive access to the
objects' state as well as to coordinate the use of an object by concurrent
threads. Synchronization can be expressed using low-level synchronization
mechanisms used independently from the object-oriented constructs. However,
this approach does not scale well if objects are to be reused in programs
which have a different thread structure. Early work on COOP [3,4,5,6]
concentrated on the design of features that integrate objects with concurrency
features providing adequate expressive power for classical concurrent
programming problems. For instance, in some proposals objects are identified
with message passing processes and asynchronous message passing variants are
introduced. In other proposals, objects are similar to monitors. They are
provided with mutual exclusion and some features are provided to coordinate
the execution of invoking threads.
Early COOP models either did
not provide support for inheritance or the use of inheritance required
substantial rewriting of inherited code to synchronize inherited methods with
those defined in subclasses. This issue has been discussed in previous
research [3,7,8,9]
and the term inheritance anomaly introduced by Matsuoka [10]
is now often used to refer to related issues. The approach commonly adopted to
avoid such problems is to synchronize method execution by the specification of
synchronization constraints on the acceptance of messages. Synchronization
constraints are specified separately from the code of methods. As methods do
not contain any synchronization code, it is easier to reuse them in subclasses
without modification. Various approaches for specifying, inheriting and
combining inherited synchronization constraints have been proposed [11,12,13,14,15,16,17,18,19,20].
In a concurrent object-oriented
program coordination between cooperating objects is traditionally expressed
through the use of concurrency constructs embedded in the implementation of
the objects. The main motivation behind the work on object coordination is to
allow coordination patterns among several objects to be specified separately
from the implementation of individual objects. The benefits of such an
approach is that it is possible to coordinate objects in ways that were not
anticipated when the objects were implemented and to allow the reuse of the
coordination patterns themselves [21,22,9].
COOP models have to provide adequate expressive power for coping with
general concurrent programming problems. This requires a choice of appropriate
programming constructs for thread creation, message passing and
synchronization. The choice of such features was the main concern of early
COOP models. Since it was identified that these models had difficulties of
taking advantage of inheritance, most work in the area concentrated on
proposals for specifying and reusing through inheritanced synchronization
constraints for method invocation. However, the proposals for the
specification of synchronization constraints are based on oversimplified COOP
models that fail in providing adequate expressive power. In particular: (i)
synchronization constraints are not compatible with the specification of
objects that have internal activities and (ii) these proposals are based on
the assumption that once a message is accepted, method execution proceeds to
completion. This overconstrains the message processing patterns that are
expressible.
The motivation behind ATOM is the design of a COOP model that
simultaneously supports (i) the specification and reuse of synchronization
constraints, (ii) adequate expressive power and (iii) object coordination. We
also wanted to be able to use the model in the development of concurrent
software and evaluate and gradually refine its features. However, we wanted to
avoid a major language development effort. This was achieved to a large extent
by the implementation and incorporation of a prototype of the model using the
dynamic features of Python (see section 5.2).
ATOM objects are
active entities that resemble multi-threaded servers that accept and process
messages in an order that is most suitable to them. Messages are processed by
the creation of a new thread within the object. In addition, threads may also
be created spontaneously at the creation of an object for executing internal
activities. Only a single thread may be active at a time within the object and
the execution of threads is non-preemptive; another thread may run only when
the current thread suspends its execution. Threads are associated with
activation conditions (discussed in section 3.3)
which determine the states of the object that are compatible with their
execution.
Central to the ATOM model are the novel features of abstract
states , state predicates and state notification .
These features are integrated with thread scheduling and message passing in
such a way that adequate expressive power for COOP, support for inheritance
and the specification and reuse of coordination algorithms are addressed
simultaneously.
Figure 1: ATOM execution model
 |
An object in ATOM may be either executing some thread or it may be waiting
for an event, such as a message invocation (other events will be discussed
later), that will resume the execution of a suspended thread. When no thread
is running or the current thread is suspended, the object is at a stable
state . The execution of an object can be represented by a sequence of
stable states as illustrated in the right part of Figure 1.
When the object is at stable state, a ready thread is scheduled for
execution using a simple round-robin algorithm. A thread is ready if it is not
waiting for an event, such as the reply to a message or a state notification
event (explained later), and the activation conditions associated with the
thread hold at that particular state.
Activation
conditions are expressed in terms of abstract states , which
represent properties of the object's state at a level of abstraction that
hides implementation details. Abstract states are defined by the programer and
their definitions may be inherited in subclasses. The state of execution is
taken here in a broad sense. It may comprise not only the values of the
object's instance variables, but also the messages that are suspended at the
object interface, the state of execution of the object's threads, etc.
A state predicate is an evaluator of abstract states associated
with an object. State predicates are objects, defined by the programmer, that
are used by the ATOM run-time to determine if an abstract state is true at a
given stable state. The ATOM run-time interacts with state predicates
following a message protocol that has to be supported by such objects. State
predicates may be associated with an object statically or dynamically at
run-time. It is also possible for a state predicate to be shared among several
objects. This last feature is used to support object coordination.
Activation conditions
are used to constrain method acceptance and more generally the execution of
the object's threads. Methods are associated with an activation condition,
expressed in terms of abstract states, that has to be true in order to run a
thread that executes the associated method. Activation conditions may be
associated to an object either statically in its class definition, or
dynamically to a particular instance at run-time. It is also possible to
associate a condition with a particular message sent to an object. Static
activation conditions defined in a class are inherited by its subclasses and
support is provided for defining generic activation conditions. Inherited
activation conditions are by default conjoined with the ones defined in
subclasses.
The programmer
can define a number of actions to be executed when certain events, such as the
receipt of a message, the invocation and completion of a method and the
suspension and resumption of a thread, occur. In these synchronization
actions the programmer may use synchronization variables
especially defined for this purpose to keep track of the occurrence of such
events. This mechanism in combination with abstract states and state
predicates can be used to define abstract states that capture aspects of the
history of object execution that are not represented in the object's state.
Synchronization actions defined in a class are inherited by its subclasses.
Thus they provide more expressive power for the specification of generic
synchronization constraints than mixins.
State
notification is one of the features provided in ATOM for supporting
object coordination. It can be used by an object to monitor and synchronize
with abstract state changes of other objects. An object that wants to be
notified when another object reaches an abstract state first issues a state
notification request to the source object. This returns a notification event
object that can be used to suspend one of its threads. State notification may
be asynchronous or synchronous. The latter ensures that when the thread in the
notified object resumes, the source object is still at the requested state.
It is important to note that state notification does not require the
explicit collaboration of the source object. This supports object coordination
in a way that promotes a high degree of code reuse at two levels: on the one
hand, objects are more reusable because they are coded without specifying
coordination constraints. On the other hand, the coordination algorithms are
more reusable as they are specified separately from the implementation of the
involved objects. In addition, as coordination is expressed on abstract
information, it is possible to specify generic coordination algorithms that
can be reused for objects with different interfaces but similar abstract
behavior.
The message passing
facilities are integrated with thread scheduling to provide adequate
expressive power in the way objects process messages, how and when they
receive replies and how they reply to messages. The following ways of sending
messages are provided:
- Blocking remote procedure call: when this type of message
passing is used, the thread and its object are blocked until the message is
received by the destination and a reply is returned. The ordinary Python
method invocation on ATOM objects has this semantics.
- Non-blocking remote procedure call: The difference between
non-blocking and blocking remote procedure call is that while the sending
thread in a non-blocking remote procedure call waits for the reply, other
threads may run in the object. The suspended thread is resumed after the
reply has been received if there is no other active thread in the object and
the object is at a state where the method associated with the thread can be
run. The non-blocking designation should be understood with respect to the
object. The calling thread itself is blocked.
- Asynchronous message passing: the calling thread sends a
message and proceeds with its execution without waiting for a reply.
However, it is possible to specify that another object, which should an
instance of the class Reply, will receive the reply. Reply
objects have an abstract state Ready and a method
getResult which is accepted at this state to retrieve the reply
later. State notification may be used on the Ready state of a
Reply object to avoid blocking an object if the result is not yet
available. The use of these features is illustrated in section 4.4.2.
In this section we show how ATOM can be
used for concurrent programming in Python and in particular how its features
address the issues discussed in section 2.
Due to space limitations we do not describe all of ATOM's features in detail.
However, we believe that the examples in this section provide a good idea on
the use of ATOM in Python. A detailed description can be found in [23].
To create an ATOM object, also called an
active object in the rest of the paper, one first defines a class
that inherits the class ActiveObjectSupport. Methods defined in this
class can be used in subclasses to access ATOM's concurrency features such as
sending messages asynchronously and suspending the object's threads.
An active object class is
created by applying the function ActiveObject2 to a class that inherits from
ActiveObjectSupport. The Python class returned from
ActiveObject is used to create active objects with the ordinary
Python object creation syntax. For example, the Buffer class in
Figure 2
can be used to create an active object class, BoundedBuffer, which is
then instantiated to create active objects:
A number of attributes defined in a
class, used to create an active object class, are interpreted in a special
way. These are shown in Table 1.
None of these has to be defined to create an active object class. However, if
the methods attribute is not defined, no method of the active of
object may be invoked by other objects. The methods attribute specifies the
list of methods that may be called by other objects. The other methods defined
in the class are considered ``private''. The other special attributes are
discussed when used in the following sections.
Table 1: Special attributes for active object
classes
Attribute |
Description |
states |
abstract states |
methods |
public methods |
state_predicates |
state predicates |
conditions |
activation conditions |
pre_actions |
pre actions |
post_actions |
post actions |
receipt_actions |
receipt actions |
activities |
internal activities |
In the definition of
the class Buffer in Figure 2,
the methods variable specifies that a buffer accepts messages for
executing its put and get methods. The states
variable defines the abstract states of the class. In the Buffer
class the abstract states empty and full are defined for
representing the corresponding states of a buffer. The association between
abstract states and state predicates is implicit. A default state predicate
object is created implicitly and the methods empty and full
are used to determine whether or not the bounded buffer is at any of these
abstract states. The conditions dictionary associates messages with
activation conditions. Activation conditions are Boolean functions that take a
single argument. A number of methods can be invoked on this argument to obtain
information on the abstract state of the object. In the Buffer class,
the messages put and get are associated with activation
conditions that constrain the acceptance of these messages at the abstract
states where the buffer is not full and not empty respectively. The method
atState is used in activation conditions to refer to abstract states
of the object.
Figure 2: Simple message acceptance
constrains
![\begin{figure}
\parbox{\myfigwidth}{\small\begin{aasrc}
\aaline{1}{\aakw{class}...
...store[0]}
\aaline{34}{\aaws{4}\aakw{return}\aaws{1}data}\end{aasrc}}\end{figure}](Concurrent Object-Oriented Programming in Python with ATOM_files/img3.gif) |
Figure 3
shows the possibility to define generic synchronization constraints as mixins.
The class lockMixin defines an abstract state locked. The
activation conditions defined in the class specify that when the object is at
the abstract state locked no method but unlock may be
accepted. The set of methods constrained by the activation condition is
specified by a function that evaluates to a list of methods. This function
uses the predefined method allMethodsExcept on its argument to obtain
the set of all methods except unlock. When this class is inherited by
some other class, allMethodsExcept will return3 the set all methods of the subclass except
unlock. Thus, the activation condition will constrain the execution
of all methods of the classes that inherit the lock mixin.
Figure 3: Generic message acceptance
constrains
 |
Figure 4
illustrates the specification and use of internal activities in ATOM. The
class adaptBuffer specializes the behavior of the bounded buffer so
that the size allocated for the buffer is increased, in a background activity,
if the buffer is full most of the time. The activities variable is
used to specify that the method extendSize is run in a new thread at
the creation of the object. This thread is run, as specified by the conditions
variable, only when the buffer is at the abstract state oftenFull.
When the thread is activated it increases the allowable buffer size,
limit, by a fixed amount, incr, then suspends its execution
to allow other threads to run. The method oftenFull is used to
determine if the buffer is at the associated state by examining if the ratio
of put messages accepted when the buffer was full is greater than
factor. This is only examined after it has received a number of
put messages greater than freq since last
extendSize was done. The information needed by oftenFull is
maintained in the synchronization variables4 put_count and full_count and
is updated using a synchronization action, monitorPut, which is
executed, as specified by receipt_action, whenever a put
message is received.
Figure 4: Internal activities
 |
As we discussed above, a
widely accepted approach for overcoming the inheritance anomaly is to keep
synchronization code separate from the code of the methods. This works well
for a pattern of processing messages where once a message is accepted the
requested method executes to completion without any further need for
synchronization. However, such an approach fails to provide adequate
expressive power for other message processing patterns. In particular, it is
hard to address the concurrent programming issues known as nested monitors
calls [24]
and remote delays [25].
These issues are illustrated in a concurrent programming pattern known as
the administrator [26].
In this programming pattern an object, we call it the server ,
accepts requests from clients and makes a number of (sub)requests to other
objects (the second-level servers ) to process the client's request.
While a second-level server processes a (sub)request, the server accepts and
processes other clients' requests. The server resumes the processing of a
client request when the replies from second-level servers are available. This
programming pattern, discussed in [25]
and [26],
is important for the following reasons:
- First, if the server can accept further requests while a second-level
server processes a subrequest, the server, its clients and the other
second-level servers do not have to stay idle waiting for it to complete the
subrequest. Other clients' requests that use different resources in the
server and need the cooperation of different second-level servers can be
processed concurrently.
- Second, the use of this pattern prevents a situation, known in
concurrent programming research as nested monitor call [24],
that may lead to a deadlock. This occurs when a second-level server may only
be reached through the server and the second-level server delays a server
message.
Figure 5: Administrative pattern
 |
Figure 5
illustrates a class Server that processes request messages
according to the administrator pattern. In its request method, the
server first creates an object of class Reply that is used to receive
the reply to an asynchronous message. Then an asynchronous message is sent to
the second-level server, server2, using send. The
replyTo argument of send specifies that the reply should be sent to
the object myReply. Then state notification is used to suspend the
thread until myReply is at the abstract state Ready. At this
point the thread is suspended and other ready threads, if any, may be run. The
suspended thread will resume after myReply is at the state
Ready, no other threads are running within the object and the object
is at a state compatible with the execution of the request method. When the
thread is resumed it retrieves the result from myReply and returns it
to the client.
Object coordination can be supported
by dynamically associating abstract states, state predicates and an activation
conditions with an object. In this case the state predicate can be an
independent object that is used to constrain the invocation of the methods of
an existing objects. Another possibility is offered by the state notification
mechanism.
We
illustrate this approach for coordinating the object execution with a version
of the dining philosophers problem. The behavior of philosophers is defined in
the Philo class shown in Figure 6.
In its eatActivity a philosopher waits until she is Hungry.
Then, she tries to get the forks by calling its getForks method. When
she has done it successfully, she eats until she is not Hungry
anymore, and then releases the forks.
Figure 6: Philosopher
 |
In its getForks method (not shown) a philosopher attempts to grab
its left and right forks sequentially. A deadlock can occur if a philosopher
gets one fork and the other fork is not available.
Figure 7: Philosophers' coordinator
 |
The PhiloCoord object, shown in Figure 7,
coordinates philosophers to provide atomicity in getting the forks: no other
philosopher can get a fork before the one trying at the moment has acquired
both her forks and started eating. The coordinator calls the
newPredObject method of each philosopher to define dynamically an
abstract state, MyTurn, and to specify itself as the state predicate
object to be called for telling whether or not the abstract state is true. It
also calls the method addCondition to associate a new activation
condition, that the state MyTurn is true, with the getForks
method of each philosopher.
When a philosopher calls its getForks method5, the ATOM run-time, before accepting the
message, calls the evalState6 method of the coordinator to check if the
abstract state MyTurn for the philosopher is true. In the
evalState method, the coordinator allows the message to be accepted
by replying 1. It then waits until the philosopher (the object argument of
evalState) is at the state Eating before accepting any
further calls. This ensures that the actions of acquiring the forks are
executed atomically with respect to other philosophers. In fact, the
coordinator could use a more complex algorithm to decide if the philosopher
should get the forks allowing to schedule the philosophers' actions.
The coordination of the philosophers provided by PhiloCoord is
completely transparent to the philosophers. The dining philosopher example
shows that the ATOM model provides synchronization mechanisms which can be
added dynamically and used to synchronize existing objects without changing
their implementation.
The use of state
notification was illustrated in section 4.4.2
to coordinate the execution of the server's thread with the Ready
state of a Reply object. More examples illustrating the use of this
feature are provided in [23].
Previous COOP
models had limitations with respect to the use of inheritance and sacrificed
the expressive power for the sake of inheriting synchronization constraints.
In our model synchronization constraints are combined through the use of
abstract states with the synchronization of internal activities and message
passing features that allow a more flexible method processing pattern. As we
have shown in section 4
these features are compatible with the use of inheritance and subsume previous
proposals for the specification of synchronization constraints.
State predicates and the
possibility to associate abstract states and activation with an object
dynamically provide support for coordination using the same features as used
for the specification of synchronization constraints. State notification
provides an alternative approach for object coordination which departs from
previous work [21,22]
where coordination is based on constraining the acceptance of messages.
Coordination may also be based on changes in the state of objects. This
approach is more suitable for coordinating the execution of objects in cases
where objects encapsulate activities that are not convenient to express as
method invocation sequences. For instance, an object that encapsulates a
device. In addition, the objects to be coordinated do not have to provide the
same message interface. Coordination is based on an abstract view of object
behavior in terms of abstract state changes.
The use of Python, and especially
the more dynamic features of the language such as the possibility to inspect
and modify class attributes, allowed us to develop a prototype of the model
without undergoing a major language development effort. The
ActiveObject function discussed in section 4.1.1
goes through the class hierarchy to construct a class that has the semantics
of the ATOM object model. Currently, ATOM is entirely written in Python and it
is structured as a class framework. This made it easier to experiment with
variations of ATOM's features. For instance, it was possible to experiment
with various ways of combining the definition of abstract states and
activation conditions of superclasses. We have also tried different approaches
for scheduling threads and supporting state notification.
The availability of Python on several platforms and the large number of
modules provided in the Python library makes it attractive to experiment with
ATOM for the development of concurrent applications. However, the current
implementation has performance overhead that are due both to ATOM features and
the way threads synchronization is handled in the Python interpreter. We are
investigating ways of overcoming these limitations. We expect that the use of
some ``free threading'' Python extension and the use of extension classes for
implementing most of ATOM code in C will provide us with major performance
improvements. Another issue in using Python in the way discussed in this
paper, is how to extend the language with new constructs. In other languages
such as Smalltalk the ability of defining blocks of code that can be passed as
arguments makes it easy to define new control structures. The presence of such
a feature in Python would simplify the specification of activation conditions.
We are currently searching for ways of achieving something similar in Python.
Although there has been substantial
research in COOP and several issues that have to be addressed by COOP models
have been identified, most research has addressed particular issues in
isolation. We have presented a COOP model, ATOM, that incorporates a number of
novel features that aim to address simultaneously several concurrent
object-oriented programming issues that have been identified by previous
research: synchronized method invocation, reuse of synchronization constraints
through inheritance, support for object-coordination and adequate expressive
power for concurrent programming.
ATOM has been incorporated in Python and we have shown examples of how it
can be used for concurrent object-oriented programming in Python. A detailed
presentation of all features of ATOM can be found in [23]
and a free prototype implementation is available through anonymous ftp from
fidji.imag.fr:/pub/michael/atom. The current version does not require
any modification to the Python language or interpreter.
The use of Python allowed us to develop a prototype and experiment with the
early design of ATOM features in developing example applications. The ATOM
prototype is itself implemented as an object-oriented framework in Python.
This made it easier to experiment with variations to ATOM's features. The fact
that ATOM is in a sense an extension of Python makes it possible to take
advantage of the rich set of modules available in the Python library to use
the ATOM model to develop concurrent applications in various application
domains.
After experimenting with ATOM in the development of simple multimedia
programming environment based on active objects, we are now working on a new
version. The main aspects under consideration in the new version are: improved
performance and distributed execution. This raises the issue of whether we
should modify the Python interpreter, construct a preprocessor or search for
other possibilities for extending Python with features such as those of ATOM.
- 1
- P. Wegner, ``Dimension of object-based language design,'' in
Proceedings OOPSLA'87, vol. 22(12) of SIGPLAN Notices,
(Orlando, Florida), pp. 168-182, ACM, Dec. 1987.
- 2
- M. Papathomas, ``Concurrency in object-oriented programming languages,''
in Object-Oriented Software Composition (O. Nierstrasz and D.
Tsichritzis, eds.), Prentice Hall, 1995.
- 3
- P. America, ``Inheritance and subtyping in a parallel object-oriented
language,'' in Proceedings ECOOP '87 (J. Bézivin, J.-M. Hullot, P.
Cointe, and H. Lieberman, eds.), vol. 276 of Lecture Notes in Computer
Science, pp. 234-242, Springer Verlag, 1987.
- 4
- O. Nierstrasz, ``Active objects in Hybrid,'' in Proceedings
OOPSLA'87 (N. Meyrowitz, ed.), vol. 22(12) of SIGPLAN Notices,
pp. 243-253, ACM, Dec. 1987.
- 5
- Y. Yokote and M. Tokoro, ``Experience and evolution of concurrent
Smalltalk,'' in Proceedings OOPSLA '87, vol. 22(12) of SIGPLAN
Notices, (Orlando, Florida), pp. 168-182, ACM, Dec. 1987.
- 6
- A. Yonezawa, E. Shibayama, T. Takada, and Y. Honda, ``Modelling and
programming in an object-oriented concurrent language ABCL/1,'' in
Object-Oriented Corcurrent Programming (A. Yonezawa and M. Tokoro,
eds.), pp. 55-89, Cambridge, Massachusetts: The MIT Press, 1987.
- 7
- D. G. Kafura and K. H. Lee, ``Inheritance in actor based concurrent
object-oriented languages,'' in Proceedings ECOOP 89 (S. Cook,
ed.), British Computer Society Workshop Series, Cambridge University Press,
1989.
- 8
- D. Caromel, ``Concurrency and reusability: From sequential to
parallel,'' Journal of Object-Oriented Programming, pp. 34-42,
September/October 1990.
- 9
- M. Papathomas, G. Blair, and G. Coulson, ``A model for active object
coordination and its use for distributed multimedia applications,'' in
ECOOP'94 Workshop on Models and Languages for Coordination of
Parallelism and Distribution (A. Yonezawa, O. Nierstrasz, and P.
Ciacarini, eds.), vol. 924 of Lecture Notes in Computer Science,
(Bologna, Italy), Springer-Verlag, July 1994.
- 10
- S. Matsuoka, K. Wakita, and A. Yonezawa, ``Analysis of inheritance
anomaly in concurrent object-oriented languages (extended abstract),'' in
Research Directions in Concurrent Object-Oriented Programming (G.
Agha, P. Wegner, and A. Wonezawa, eds.), MIT Press, 1993.
- 11
- C. Atkinson, S. Goldsack, A. D. Maio, and R. Bayan, ``Object-oriented
concurrency and distribution in DRAGOON,'' Journal of Object-Oriented
Programming, March/April 1991.
- 12
- L. Bergmans, Composing Concurrent Objects.
PhD thesis,
University of Twente, 1994.
- 13
- S. Crespi Reghizzi, G. G. de Paratesi, and S. Genolini, ``Definition of
reusable concurrent software components,'' in Proceedings of ECOOP'91,
Geneva, Switzerland, vol. 512 of Lecture Notes in Computer
Science, pp. 148-166, Springer Verlag, July 1991.
- 14
- S. Frølund, ``Inheritance of synchronization constraints in concurrent
object-oriented programming languages,'' in Proceedings ECOOP 92
(O. L. Madsen, ed.), vol. 615 of Lecture Notes in Computer Science,
(Utrecht), pp. 185-196, Springer Verlag, June/July 1992.
- 15
- S. Krakowiak, M. Meysembourg, H. N. Van, M. Riveill, C. Roisin, and X.
R. de Pina, ``Design and implementation of an object-oriented strongly typed
language for distributed applications,'' Journal of Object-Oriented
Programming, vol. 3, pp. 11-22, September/October 1990.
- 16
- P. Löhr, ``Concurrency annotations for reusable software,''
Communications of the ACM, vol. 36, pp. 8-89, September 1993.
- 17
- C. McHale, Synchronization in Concurrent Object-Oriented Langauges:
Expressive Power, Genericity and Inheritance.
PhD thesis,
University of Dublin, Trinity College.
- 18
- S. Matsuoka, K. Taura, and A. Yonezawa, ``Highly efficient and
encapsulated re-use of synchronisation code in concurrent object-oriented
languages,'' in Proceedings OOPSLA'93, vol. 28(10) of ACM
SIGPLAN Notices, pp. 109-129, October 1993.
- 19
- F. Sanchez et al., ``Issues in composability of synchronization
constraints in concurrent object-oriented languages,'' in Workshop
Reader of the 10th. European Conference on Object-Oriented Programming,
ECOOP¹96 (M. Muhlhauser, ed.), Special Issue in Object-Oriented
Programming, (Linz, Autria), July 1996.
- 20
- C. Tomlinson and V. Singh, ``Inheritance and synchronization with
enabled sets,'' in ACM SIGPLAN Notices, Proceedings OOPSLA'89, pp.
103-112, Oct. 1989.
- 21
- M. Aksit, K. Wakita, J. Bosch, L. Bergmans, and A. Yonezawa,
``Abstracting object interactions using composition filters,'' in
Prooceedings of the ECOOP'93 Workshop on Object-Based Distributed
Programminng (R. Guerraoui, O. Nierstrasz, and M. Riveill, eds.), vol.
791 of Lecture Notes in Computer Science, pp. 152-184, Springer
Verlag, 1994.
- 22
- S. Frølund and G. Agha, ``A language framework for multi-object
coordination,'' in Proceedings ECOOP 93, vol. 707 of Lecture
Notes in Computer Science, pp. 346-360, Springer Verlag, July 1993.
- 23
- M. Papathomas, ``ATOM: An active object model for enhancing reuse in the
development of concurrent software,'' Research Report RR 963-I-LSR-2,
IMAG-LSR, Grenoble, France, November 1995.
(Available through anonymous
ftp at fidji.imag.fr:/pub/michael/atom/atom-report.ps.gz).
- 24
- A. Lister, ``The problem of nested monitor calls,'' Operating
Systems Review, pp. 5-7, July 1977.
- 25
- B. Liskov, M. Herlihy, and L. Gilbert, ``Limitations of synchronous
communication with static process structure in languages for distributed
computing,'' in Proceedings of the 13th ACM symposium on Principles of
Programming Languages, (St. Petersburg, Florida), 1986.
- 26
- W. Gentleman, ``Message passing between sequential processes: the reply
primitive and the administrator concept,'' Software-Practice and
Experience, vol. 11, pp. 435-466, 1981.
Footnotes
- ...Andersen1
- This work has been supported by a NATO Science Fellowship through The
Norwegian Research Council and was carried out while being a visiting
student at the Computing Department, Lancaster University.
- ...ActiveObject2
- In the next release of ATOM it is no longer needed to invoke the
ActiveObject function provided that the __init__ method of
ActiveObjectSupport is invoked.
- ...return3
- This function is called just once at the creation of the active object
class.
- ...variables4
- Attributes used for synchronization purposes; updated in synchronization
actions and red by state predicates.
- ...method5
- The call is made using non-blocking remote procedure call to avoid the
nested monitor call problem.
- ...evalState6
- This is part of the protocol supported by state predicate objects.