ns_critsec - Operate on critical section objects
The ns_critsec command provides a mechanism for creating and managing critical section objects, which are used for synchronizing access to shared resources in a multithreaded environment. Critical sections ensure that only one thread can access a protected code section at a time, preventing data corruption and ensuring thread safety.
Initializes a new critical section object and returns a handle (csid) to it. This handle is used in other ns_critsec commands to reference the critical section.
Destroys the critical section object identified by csid and frees any resources it was using. NOTE: In the current implementation, this command is effectively a no-op; the critical section will remain until the server shuts down.
Enters the critical section csid. The thread will block if another thread is already in the critical section. Enters the critical section identified by csid. The actual thread will block other threads trying to enter the same critical section. If csid was not created beforehand, it is auto-created (not recommended for best practices).
Evaluates the provided script inside the critical section identified by csid. This command ensures the script runs with exclusive access to the critical section. If csid was not created beforehand, it is auto-created (not recommended for best practices).
Leaves the critical section identified by csid. If a thread has entered the critical section multiple times, it must call csid as many times as it entered. When a thread fully exits the critical section, a notification is sent to other threads waiting on the same critical section.
The following example demonstrates the usage of ns_critsec commands to safely access and modify a shared resource:
# # Create a critical section and store its handle # nsv_set . log_critsec [ns_critsec create] proc log_message {message} { set critsec [nsv_get . log_critsec] # # Enter the critical section to ensure only one thread writes at a time # ns_critsec enter $critsec set timestamp [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"] set handle [open "shared_log.txt" "a"] puts $handle "$timestamp - $message" close $handle ns_critsec leave $critsec } # # Example of multiple threads writing to the log file # (assuming, the proc "log_message" was loaded before and is # available in all threads) # ns_thread create -detached { log_message "Thread 1: Starting process" } ns_thread create -detached { log_message "Thread 2: Completed task A" } ns_thread create -detached { log_message "Thread 3: Encountered an error" }
Explanation:
The log_message procedure ensures that only one thread at a time writes to the shared log file.
This prevents overlapping or incomplete log entries and ensures log data integrity.
Each thread can safely call log_message, and the critical section guarantees exclusive access during the write operation.