Files
GacUI/.github/KnowledgeBase/KB_VlppOS_MultiThreading.md
2025-10-30 22:39:15 -07:00

3.8 KiB

Multi-threading

Cross-platform threading primitives and synchronization mechanisms for concurrent programming.

Thread Pool Operations

Use ThreadPoolLite::Queue and ThreadPoolLite::QueueLambda for thread pool execution.

Use static functions ThreadPoolLite::Queue or ThreadPoolLite::QueueLambda to run a function in another thread.

ThreadPoolLite Benefits

The thread pool provides several advantages over manual thread creation:

  • Automatic thread lifecycle management
  • Resource pooling to avoid thread creation overhead
  • Better system resource utilization
  • Simplified concurrent programming model

Usage Examples

// Queue a function pointer
ThreadPoolLite::Queue(someFunction);

// Queue a lambda expression
ThreadPoolLite::QueueLambda([]() {
    // Work to be done in background thread
});

Thread Control Operations

Thread Pausing

Use Thread::Sleep for thread pausing.

Use static function Thread::Sleep to pause the current thread for some milliseconds.

Thread Identification

Use Thread::GetCurrentThreadId for thread identification.

Use static function Thread::GetCurrentThreadId to get an identifier for the OS native thread running the current function.

Manual Thread Creation

Use Thread::CreateAndStart only when thread pool is insufficient.

Thread::CreateAndStart could be used to run a function in another thread while returning a Thread* to control it, but this is not recommended. Always use ThreadPoolLite if possible.

When to Use Manual Threads

Manual thread creation should only be considered when:

  • You need fine-grained control over thread lifecycle
  • Thread-specific configurations are required
  • The thread pool doesn't meet specific timing requirements
  • Working with legacy code that requires direct thread handles

Thread Pool with Synchronization

A ThreadPoolLite call with an EventObject is a better version of Thread::Wait.

This approach provides better resource management and avoids the complexities of manual thread synchronization.

Extra Content

Threading Best Practices

  1. Prefer Thread Pool: Use ThreadPoolLite for most concurrent operations
  2. Avoid Thread Creation: Manual thread creation adds overhead and complexity
  3. Use Synchronization Primitives: Combine threading with proper synchronization objects
  4. Handle Exceptions: Ensure proper exception handling in threaded code

Performance Considerations

  • Thread Pool: Minimal overhead for task scheduling and execution
  • Thread Creation: Significant overhead for creating and destroying threads
  • Context Switching: Consider the cost of frequent context switches
  • Resource Contention: Be aware of shared resource access patterns

Cross-Platform Considerations

The threading API provides a unified interface across platforms:

  • Windows: Uses Windows thread API internally
  • Linux: Uses pthread API internally
  • Behavior remains consistent across platforms
  • Thread IDs are platform-specific but the API is uniform

Memory Management

  • Thread pool automatically manages worker threads
  • Manual threads require explicit cleanup
  • Lambda captures should be carefully managed for thread safety
  • Avoid capturing references to stack variables in threaded lambdas

Error Handling

Threading operations can fail due to:

  • System resource exhaustion
  • Permission restrictions
  • Platform-specific limitations

Always check return values and handle potential failures gracefully.

Integration with Synchronization

Multi-threading works best when combined with appropriate synchronization primitives:

  • Use with Mutex for cross-process synchronization
  • Combine with CriticalSection for in-process protection
  • Integrate with EventObject for thread coordination
  • Apply ConditionVariable for complex waiting scenarios