lock [name] [mutex] [timeout]
lock- [name]
name - lock object name. Must be like a variable name. Without quotes. Used to identify the same lock object in multiple functions (or macros, etc). Can be omitted or literal 0 if the lock object is used only in current function. The lock object is a hidden global variable. It is initialized when lock is executed first time.
mutex - mutex name. String. Case sensitive. Can contain any characters except \. Can have "Global\" or "Local\" prefix. Read more in remarks.
timeout - number of milliseconds to wait in case another thread is executing locked code. Integer. On timeout throws error that can be handled by err. If omitted or -1, waits indefinitely. To just check whether the code is locked, use 0.
Options: - unlock.
Added in QM 2.2.0.
A thread is a running function or macro. Multiple threads can run simultaneously. It means that two or more threads can execute the same code block at the same time. Sometimes it is important to prevent this. For example, if one thread is writing to a file (e.g. using str.setfile), another thread would fail to open the file at that time. Or, if one thread is modifying a global variable, the value of the variable may become incorrect if another thread also modifies it at the same time. Use lock to avoid this.
Locks the following block of code (code from lock to lock- or to the end of the function). It means that the code cannot be executed by more than one thread at a time. If thread2 wants to execute the code while thread1 is executing it, thread2 waits until thread1 finishes executing the code.
Unlocks the code block that was locked by lock. Unlocking in many cases is not necessary. QM automatically unlocks the code when the function exits.
If name was used with lock, use the same name with lock-.
lock- unlocks the code only if it was actually executed. For example, if you goto somewhere without executing lock-, the code remains locked.
------
You can use the same named lock object (the same name) in multiple functions. For example, while one thread is executing locked code in function1, other threads also will not be able to execute locked code in function2 if the code is locked with the same lock object.
Don't use multiple lock without associated lock-. The lock count is incremented (by 1) by lock and decremented (by 1) by lock- and when the function exits. If the lock count is more than 1 when the function exits, all code locked by that lock object remains locked. To reset, you can execute lock- somewhere else, or restart QM.
Be careful using lock. Two threads can lock each other, causing both to wait forewer. Example: Thread1 is executing locked code and sends message to a window of thread2. Thread2 receives the message and tries to execute the same code (or other code locked by the same lock object). Result: Thread1 waits in SendMessage (because thread2 waits in lock), and thread2 waits in lock (because thread1 waits in SendMessage). To reset, restart QM.
While waiting in lock, the thread does not process messages, even if opt waitmsg is used.
If mutex is omitted or "", the lock object synchronizes only threads in current process (running program). Using a mutex allows synchronizing threads between processes. It can be useful, for example, if 'Run in separate process' is checked (see exe). Using a mutex is about 8 times slower. The mutex is created or opened when initializing the lock object. The mutex name must be an unique string, like "QM_mutex_macroname_8469". Error if a kernel object of other type with the same name exists in the system. A mutex with "Global\" prefix can be used by processes in multiple user sessions (fast user switching).
lock str s="test" s.setfile("$desktop$\test.txt") lock- lock 0 "QM_mutex_test1" ... lock- lock 0 "" 1000; err end "the code is locked more than 1 s" ... lock- lock shared_lock_object ... lock- shared_lock_object