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
|
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.
This document was generated using the
LaTeX2HTML translator version 97.1.
Michael Papathomas,
Anders Andersen, Fri Sep 19 14:54:44 1997