Thread Part 1: Use the Force, Luke

By Dan Haines & Dave Navarro, Jr.

Today's software is becoming increasingly more complex. Where users would previously use two or more separate applications to perform tasks, you'll find a single application to perform all of the same tasks. Consolidating all of these tasks into a single application makes it easier on the end user, who now needs to deal with only a single user-interface.

But bringing the functionality of more than one task into a single program doesn't always result in better productivity. In today's modern operating systems, users can use multi-tasking to execute more than one program at a time. Bringing all of those tasks into a single program could prevent the end user from running more than a single task at a time if the application does not support multi-threading.

What is Multi-Threading?

A Thread is a Sub or Function in a program which executes from beginning to end. Multi-Threading is the ability to execute more than one Sub or Function at the same time in a single application. This is different from Multi-Tasking which is where the operating system executes more than one program at a time. Before the advent of multi-threading support in operating systems like Windows 95 and Windows NT, many applications would launch a completely separate program to perform simultaneous tasks. While in many cases the end result would be the same, it is much harder to keep the tasks synchronized since two separate tasks can't share variables or arrays.

For example, you may have a word processing application which allows you to print your document to a printer at the same time that it allows you to make changes to that same document. When instructed to print, the software creates a separate thread which handles the process of printing the document. The computer is able to execute both threads simultaneously and you are not forced to wait for printing to finish before continuing to edit the document.

Another example might be in a control environment where continuous data is being received from multiple external sources via intranet and/or internet communication links. For this example the data is input, processed, saved, output and or printed continuously. A thread could be set up to generate each new array as needed. Other thread(s) to receive the input data and populate the input array, another thread to process an array’s input data packet in real-time, another thread to safe-store the input array when fully populated. A final thread to output or display selected data elements after being processed. Multi-threading would allow each thread in this application to utilize the CPU’s available time and resources in a given priority and upon data availability by the other threads.

Uh oh, This Sounds Hard

While the advantages and features of multi-threading is exciting stuff, there is a common misconception that multi-threading is difficult to implement and should only be attempted by C++ programmers who have spent years studying the intricacies of system-level programming. This simply isn't true. Starting a new thread is as easy as calling a single API function telling the Windows operating system that you want a Sub or Function to execute concurrently with your own program. In fact, you can have many threads running inside of the same program, limited only by available memory.

That's not to say that everything is a bed of roses. Depending on what your program does, and how its written, synchronization and re-entrancy are critical issues which have to be addressed. If you've written an application which uses separate threads for loading documents or data files and printing them, you don't want the Print thread to begin executing until after enough of the document or data file has been loaded into memory. But as long as you plan for it when you begin designing your application, adding synchronization support to your code is an easy task.

So, Why Doesn't Visual Basic Support Multi-Threading?

Actually, that's a very good question, and one that only Microsoft can answer. In order to support multi-threading in a language, the Run-Time Library (the code that is executed when you use a language statement or function) needs to support re-entrancy. Typically, this is done by making all internal variables local on the stack or by using some form of synchronization. As noted above, this really isn't that hard to accomplish, just time-consuming. There is certainly nothing inherent in the Basic language to prevent it from supporting multiple-threads.