The default behavior for an application client is to be single-threaded. This means that only one thread, the main thread, exists in the client process. All application and RPC runtime execution takes place within this single thread. This behavior applies only to clients that use the User Datagram Protocol (UDP). If another protocol sequence is used for RPC transport, the RPC runtime will spawn several threads and revert to multithreaded behavior.
Single-threaded behavior, compared to multithreaded client behavior, provides several benefits to application developers:
· Debugging is easier. Using advanced thread-aware debuggers and following code execution through multiple thread context switches are unnecessary. The same debugging techniques and tools used to debug standard applications can be used to debug an RPC client.
· Usage of system resources is lower. The DCE Threads runtime is not initialized in single-threaded mode. This means startup time will be faster, less memory will be used, and performance will improve because context switching does not take place.
· Linking libraries that are not thread-safe into DCE applications is less dangerous. Some third-party libraries depend on default behavior from certain operating system functions. However, in a multithreaded process, this behavior is defined differently. Examples of this include signal handling, I/O, and fork and exec functions. When an application client is single-threaded, the default behavior for these functions is guaranteed, and without risk when using libraries that are not thread-safe.
If any application-level threads are created in the RPC client, the single-threaded process immediately reverts to multithreaded behavior. This means that both the RPC runtime and DCE Threads runtime will be initialized and create several runtime-level threads, and the benefits described for a single-threaded client will not longer apply. Once the client becomes multithreaded, it remains so even if all of the user-level threads have terminated.
Existing applications can take advantage of single-threaded mode without requiring changes to the code. As long as the client is using the UDP protocol sequence and has not performed a pthread_create call, single-threaded behavior automatically remains; applications can continue to make pthread API calls and remain in single-threaded mode. If, for example, the application creates mutex variables, and even locks or unlocks these variables, these calls will behave correctly and not cause the process to become multithreaded. However, after the first pthread_create call takes place in the client application, it becomes multithreaded and all previously initialized pthreads primitives will function as expected in a multithreaded environment.
To implement single-threaded behavior, the DCE Threads library performs its initialization in two phases:
· Phase 1 occurs when the first pthread API call is made. This initializes mutexes, condition variable, and attributes.
· Phase 2 occurs when the first pthread_create call is made. This initializes the remaining DCE Threads functionality, including thread management, context switching, the creation of a null background thread, and all of the multithreaded operating system behavior as described in the Introduction to Multithreaded Programming topic.