Storage usage and threaded applications

When you write a threaded application, it is important to understand the visibility and scope of various classes of storage.

When your application declares variables, multiple threads might be able to access or use these variables. The visibility and scope of the storage that are used for the variables of the application affect the function of the application.

  • Global storage

    Global storage that you declare in one of your application source files is visible to all other source files or modules in your application. All threads that run code in your application share the same global storage. This unintended sharing of storage is a common safety problem.

  • Static storage

    Static storage is global storage with visibility that is restricted to the source file, module, or function in which the storage or variable was declared. All threads that run code from that module share the same static storage.

  • Thread local storage

    A thread local storage variable is visible to all source files in your application, a single source module, or a single function, depending on how the variable is declared. Thread local storage is not visible to other threads in the process. When a thread is started, copies of thread local storage variables are created for the thread.

  • Heap storage

    Heap storage is allocated and deallocated dynamically by your application (for example, by malloc() and free() in C, or new and delete in Java™ or C++). All threads that run code in your application share the same heap.

    If you give another thread a pointer to the heap storage that has been allocated (by storing the pointer in static or global storage, or by otherwise passing the pointer to another thread), that thread can use or deallocate the storage. This unintended sharing of storage is a common thread safety problem.

  • Automatic storage

    Automatic or local storage is allocated automatically by your language when you declare a variable that is private to a function, method, or subroutine. Local storage is not visible to other threads in the process. Each time those threads call the function, method, or subroutine, the thread allocates new versions of the automatic variables. Each thread gets its own automatic storage. A thread should not access automatic storage from another thread because of the complex serialization and synchronization issues involved.

The operating system further restricts the scope of global, static, thread local, and heap storage to the activation group that your application code is running in. This means that application code or threads, which are running in different activation groups but are using the same global or static variables, access different versions of those variables and their storage. Similarly, heap storage allocated in one activation group might not be deallocated in another activation group, although the storage can be used by different activation groups.

Some languages support only global or static storage classes for variables. These languages are not easy to use in threaded applications. You should not use threads in these languages.