Creating Multithreaded Applications with WATCOM VX-REXX

by Brian Vink

The integrated graphical user interface (GUI) and multithreading capability of the OS/2 operating system are two of its key advantages. The integrated GUI provides the framework necessary for rich, graphical applications. Multithreading enables simultaneous running of many applications. WATCOM's VX-REXX provides an easy-to-use development environment for creating applications that exploit both the GUI capabilities and multithreading of OS/2 2.x. In this article we focus on multithreading. We briefly discuss threads and then show how to create a simple multithreaded application using WATCOM VX-REXX.

Why Threads?
A thread is a unit of execution. It has its own instructions, related CPU register values, and a stack. A thread does not own system resources, but it shares the resources owned by the process that created it. A program that uses threads will appear to be able to do more than one thing at a time.

The IBM OS/2 Application Design Guide states "The most efficient use of your system will be achieved if you structure your application so that one thread remains responsive to user input while others continue processing work." An example of this occurs in any OS/2 application that uses the Presentation Manager (PM) GUIs. These applications, if properly designed, have a minimum of two threads. One thread handles the processing for your application, while the other remains responsive to user input. If this is not done, your application, as well as all other PM applications, will be blocked. That is, they will be unable to receive any user interface messages. VX-REXX automatically creates applications having two threads to properly handle PM.

Many applications require more than the minimum number of threads. For instance, a process might create a thread to perform a lengthy database query or to write data to a disk or to display a movie in a multimedia presentation. The creation of this thread frees the rest of the application so that it can continue to do other things, like process user input. The following example shows how to develop this kind of multithreaded application in VX-REXX.

A Multithreaded Application
The sample application has a main window running on a single thread. By pressing the Spawn New Thread button, you can start multiple child windows (each running on a separate thread). Once started, each child window can send text messages to the main window. Figure 1 shows the sample application begin created in the WATCOM VX-REXX visual-design environment. This is the same visual design environment used when creating any VX-REXX application.



Figure 1. Sample VX-REXX application

Starting a New Thread
Figure 2 shows the main window of the application running. The main thread of the application is called thread 1. From the main window we can create any number of additional threads.



Figure 2. Main thread of the application

To spawn the new thread, we defined a procedure in the Main window to execute the following set of instructions: call VRMethod "Application", "StartThread", "Window2", threadID if( result = 0 )then do    call VRMessage VRWindow, "Could not spawn thread", "Spawn Error" end This code tells VX-REXX to start a new thread running the previously-defined Window2 code. The value of the variable thread ID is passed to the Window2 REXX code as an argument, just as if it had been started from the OS/2 command line. Figure 3 shows the result of running the previous code segment by pressing the Spawn New Thread button shown on the application screen.



Figure 3. The result of pressing the Spawn New Thread button

Communication between Threads
To synchronize the operation of the threads, we need a way for them to communicate. Using a method called posting, messages can be sent to a particular thread. For example, if we would like Window2 to pass a message to the main window, we post a message from Window2 as follows: text = VRGet( "input_window", "value" ) // Concatenation of quotes forms the string to pass // text = '"' || text || '"' call VRMethod "Application", "Post", mainThread, "call ShowMessage" text The VRGet function retrieves the text from the input box in Window2. The function posts a message to the main window. The message is a REXX command that is executed in the main window. In this case, the message is: call ShowMessage text As in all PM applications, there is an event loop that receives and dispatches messages. The message posted to the Main window is queued so that the procedure, ShowMessage, is automatically called the next time the event loop is executed.

The ShowMessage procedure of Window1 is: ShowMessage: text = Arg( 1 ) call VRMethod "message_list", "addstring", text return In this example, ShowMessage simply lists the message that has been passed to it in its message box. Figure 4 shows a message that was passed to the main thread from thread 2.



Figure 4. Message passed to the main thread

The method described previously is not the only method of communicating between threads. Other methods, such as using process-wide global variables, are also supported by WATCOM VX-REXX.

In summary, an integrated GUI and support of multithreading are two of the many benefits offered by OS/2 2.x. WATCOM VX-REXX exploits both of these key features of OS/2 in one cost effective package. VX-REXX is ideal for both simple development projects and the creation of advanced applications requiring the advanced features of OS/2 2.x.

Watcom History
Founded in 1974, WATCOM supplies high-performance programming and information tools for a wide range of computing environments. For more information on WATCOM or VX-REXX, contact WATCOM at:
 * WATCOM International
 * 415 Phillip Street
 * Waterloo, Ontario
 * Canada N2L3X2
 * 519-886-3700
 * 519-747-4971

or
 * WATCOM Europe
 * PO Box 64
 * LIVINGSTON
 * West Lothian 5H547AE
 * 44 506 460112 (phone)
 * 44 506 460115 (fax)