Sequential Composition and Explicit Thread Creation

  • Main Home Page

  • Features

  • Sequential Composition and Explicit Thread Creation

  • Objects

  • Exception Handling

  • Syntax Improvements

  • Standard Modules

  • Window Programming

  • Finite Domain Constraints

  • Record Constraints

  • Efficiency

  • Tools

  • Documentation

  • Download


  • Sequential Composition

    The major change from Oz 1 to Oz 2 is that Oz 2 is based on sequential composition while Oz 1 is based on concurrent composition. Oz1 creates new threads automatically when needed. Oz 2 creates new threads only when this is explicitly requested with the statement

    thread Statement end

    Sequential composition and explicit thread creation lead to a different concurrent programming style. To port a concurrent Oz 1 program to Oz 2, it will be necessary to insert thread ... end at the right places. To do this, you will have to understand the concurrent structure of your program.

    We changed to sequential composition because it makes programming and debugging substantially easier.

    Objects and Locks

    Since Oz 2 has sequential composition, it also has first-class locks to synchronize data structures that are accessed by more than one thread.

    The change to sequential composition led to a redesign of the object system. While in Oz 1 objects are always synchronized, they must be synchronized explicitly with locks in Oz 2. Sequential object-oriented programming in Oz 2 is easier than in Oz 1 since it is impossible to create a deadlock. Concurrent object-oriented programming in Oz 2 requires the explicit use of locks. Locks provide more flexibility than the built-in object synchronization of Oz 1.

    Implicit Thread Creation

    That thread creation is always explicit in Oz 2 (i.e., caused by thread ... end) is not completely true. There are two simple exceptions:

    1. Every statement that is fed through the programming interface is automatically enclosed into thread ... end. Thus statements fed through the programming interface run concurrently.
    2. The finite domain propagators always run concurrently.

    Terminology Change

    We have changed our terminology. In Oz 2 we call a statement what is called an expression in Oz 1, and we call an expression what is called a term in Oz 1.

    Oz 1 Oz 2
    expression becomes statement
    term becomes expression

    Example

    Let's discuss the difference between Oz 1 and Oz 2 with an example. Consider the statement

    local X=2 Y=3 Z U in
       U = Z*Z
       Z = X+Y
       {Browse Z}
    end
    

    In Oz 1 this statement will display 25 in the browser. It will do so by creating a new thread for the statement U = Z*Z.

    In Oz 2 this statement will not display anything. The executing thread will simply block for ever at the statement U = Z*Z because Z is not determined.

    To make the statement work in Oz 2, we can rewrite it as follows:

    local X=2 Y=3 Z U in
       thread U = Z*Z end
       Z = X+Y
       {Browse Z}
    end
    

    Reduction Strategy

    Oz 1's reduction strategy cannot be expressed in Oz 2. The reason is that

    thread Statement end
    

    will create a new thread no matter whether it is needed or not. It turns out that the automatic thread creation of Oz 1 is not needed.

    There is no direct translation of Oz 2 programs into Oz 1 programs. One can try to simulate sequential composition with data flow synchronization, but this may require many auxiliary variables and nonlocal program transformations. For instance, procedures will need an extra argument so that they can signal that they have done their job completely.

    Example

    Here is another example for rewriting an Oz 1 program into an Oz 2 program:

    fun {Map Xs F}
       case Xs
       of nil then nil
       [] X|Xr then {F X} | {Map Xr F}
       end
    end
    

    In Oz 1, Map is automatically concurrent. For instance,

    {Browse {Map [1 2 _ 3 4] fun {$ X} X+1 end}}
    

    will show [2 3 _ 4 5] in the browser. In Oz 2 you will see nothing since Map will block on the undetermined element of the list and hence Browse will not be applied. However, it is easy to write a concurrent Map in Oz 2:

    fun {Map Xs F}
       case Xs
       of nil then nil
       [] X|Xr then thread {F X} end | {Map Xr F}
       end
    end
    

    Gert Smolka