Threading Controls

The Threading tab provides 8 controls for concurrent programming: threads, synchronization primitives, thread pools, and inter-thread communication channels. All controls are cross-platform and use native OS threading facilities.

TThread CT_THREAD = 63

Executes code in a separate OS thread. The primary building block for concurrent operations.

PropertyTypeDefaultDescription
nPriorityNumeric0Thread priority (-2 lowest to +2 highest)
lFreeOnTerminateLogical.F.Automatically destroy object when thread ends
lRunningLogical.F.Thread is currently executing (read-only)
lFinishedLogical.F.Thread has completed (read-only)
nThreadIdNumeric0OS thread identifier (read-only)
EventCategoryDescription
OnExecuteLifecycleCode to run in the thread (required)
OnTerminateLifecycleThread finished execution (called on main thread)
MethodDescription
Start()Begin thread execution
Wait( nTimeout )Wait for thread to finish. Optional timeout in ms
Cancel()Request cooperative cancellation
PlatformNative Implementation
WindowsCreateThread / _beginthreadex
macOSpthread_create
Linuxpthread_create

TMutex CT_MUTEX = 64

Mutual exclusion lock. Ensures only one thread accesses a shared resource at a time.

MethodDescription
Lock()Acquire the mutex. Blocks if already locked by another thread
Unlock()Release the mutex
TryLock()Attempt to acquire without blocking. Returns .T. if acquired
PlatformNative Implementation
WindowsCRITICAL_SECTION
macOSpthread_mutex_t
Linuxpthread_mutex_t

TSemaphore CT_SEMAPHORE = 65

Counting semaphore. Controls access to a pool of shared resources with a limited count.

PropertyTypeDefaultDescription
nInitialCountNumeric0Initial semaphore count
nMaxCountNumeric1Maximum semaphore count
MethodDescription
Wait( nTimeout )Decrement count. Blocks if count is zero. Optional timeout in ms
Signal()Increment count. Wakes one waiting thread

TCriticalSection CT_CRITICALSECTION = 66

Lightweight synchronization primitive. Faster than TMutex for protecting short code sections within the same process.

MethodDescription
Enter()Enter the critical section. Blocks if another thread is inside
Leave()Leave the critical section
TryEnter()Attempt to enter without blocking. Returns .T. if entered

TThreadPool CT_THREADPOOL = 67

Manages a pool of reusable worker threads. Submit tasks to the pool instead of creating individual threads.

PropertyTypeDefaultDescription
nMinThreadsNumeric2Minimum number of worker threads
nMaxThreadsNumeric8Maximum number of worker threads
nQueueSizeNumeric256Maximum pending task queue size
nActiveThreadsNumeric0Currently active worker threads (read-only)
nPendingTasksNumeric0Tasks waiting in the queue (read-only)
EventCategoryDescription
OnTaskCompleteLifecycleA task finished execution. Params: xResult, nTaskId
OnErrorErrorA task raised an error. Params: oError, nTaskId
MethodDescription
Submit( bTask )Add a task (code block) to the queue. Returns nTaskId
WaitAll( nTimeout )Wait for all pending tasks to complete
Shutdown()Stop all threads after completing pending tasks

TAtomicInt CT_ATOMICINT = 68

Lock-free atomic integer. Provides thread-safe counter operations without explicit locking.

MethodDescription
Inc()Atomically increment by 1. Returns new value
Dec()Atomically decrement by 1. Returns new value
Get()Read current value
Set( nValue )Atomically set to nValue
CompareExchange( nExpected, nNew )If current == nExpected, set to nNew. Returns .T. if swapped
Add( nValue )Atomically add nValue. Returns new value
PlatformNative Implementation
WindowsInterlockedIncrement / InterlockedCompareExchange
macOS__atomic builtins (GCC/Clang)
Linux__atomic builtins (GCC/Clang)

TCondVar CT_CONDVAR = 69

Condition variable. Allows threads to wait until a particular condition is signaled by another thread.

MethodDescription
Wait( oMutex, nTimeout )Release mutex and wait for signal. Re-acquires mutex on wake. Optional timeout in ms
Signal()Wake one waiting thread
Broadcast()Wake all waiting threads
PlatformNative Implementation
WindowsCONDITION_VARIABLE
macOSpthread_cond_t
Linuxpthread_cond_t

TChannel CT_CHANNEL = 70

Thread-safe message channel for inter-thread communication. Inspired by Go channels and CSP concurrency.

PropertyTypeDefaultDescription
nBufferSizeNumeric0Buffer capacity (0 = unbuffered/synchronous)
lClosedLogical.F.Channel has been closed (read-only)
MethodDescription
Send( xValue )Send a value to the channel. Blocks if buffer is full
Receive()Receive a value from the channel. Blocks if empty
TryReceive( @xValue )Non-blocking receive. Returns .T. if a value was available
Close()Close the channel. No more values can be sent
EventCategoryDescription
OnReceiveDataValue received (alternative to polling). Params: xValue

Code Example: Producer-Consumer Pattern

// Producer-Consumer pattern using TChannel and TThread

FUNCTION Main()

   LOCAL oChannel, oProducer, oConsumer

   // Create a buffered channel with capacity 10
   oChannel := TChannel():New()
   oChannel:nBufferSize := 10

   // Producer thread: generates work items
   oProducer := TThread():New()
   oProducer:lFreeOnTerminate := .T.
   oProducer:OnExecute := { || ProduceItems( oChannel ) }

   // Consumer thread: processes work items
   oConsumer := TThread():New()
   oConsumer:lFreeOnTerminate := .T.
   oConsumer:OnExecute := { || ConsumeItems( oChannel ) }

   // Start both threads
   oProducer:Start()
   oConsumer:Start()

   // Wait for producer to finish, then close channel
   oProducer:Wait()
   oChannel:Close()

   // Wait for consumer to drain remaining items
   oConsumer:Wait()

   QOut( "All done!" )

RETURN NIL

FUNCTION ProduceItems( oChannel )

   LOCAL n

   FOR n := 1 TO 100
      oChannel:Send( "Task #" + Str( n ) )
      QOut( "Produced: Task #" + Str( n ) )
   NEXT

RETURN NIL

FUNCTION ConsumeItems( oChannel )

   LOCAL xItem

   DO WHILE ! oChannel:lClosed .OR. oChannel:TryReceive( @xItem )
      xItem := oChannel:Receive()
      IF xItem != NIL
         QOut( "Consumed: " + xItem )
      ENDIF
   ENDDO

RETURN NIL
8 Threading Controls

All threading primitives map directly to native OS facilities for maximum performance. Use TChannel for safe inter-thread communication instead of shared variables with locks.

On This Page

TThread CT_THREAD = 63 TMutex CT_MUTEX = 64 TSemaphore CT_SEMAPHORE = 65 TCriticalSection CT_CRITICALSECTION = 66 TThreadPool CT_THREADPOOL = 67 TAtomicInt CT_ATOMICINT = 68 TCondVar CT_CONDVAR = 69 TChannel CT_CHANNEL = 70 Code Example: Producer-Consumer Pattern