That's true, and I apologize, but I did write my code before you wrote that. Also, I still don't know what a plugin window is, or what a blank app is. So I'm not qualified to solve this.
How to do this, I still don't understand
Read this page to find out about locks. The important part for you at the moment is
- Place a Semaphore Lock Action (using the same Semaphore Name) as the first action of each Macro that you wish to prevent executing simultaneously.
Thanks for the laugh.
Thank this is helpful and very clear. I keep coming back to this because when I triggered subroutines they were completing the action but I needed to add to the subroutine to wait until a menu item was visably seen as checked or unchecked rather than in my case using the Semaphore Lock. The subroutines were not checked as asynchronously enabled either so it took some headscratching to figure this one out. action:Execute a Macro [Keyboard Maestro Wiki]
Would you ever put a Semaphore lock inbetween different subroutines of a single macro?
It's hard for me to even think of what would need these or how to put together an example macro that would need this unless it is two macros that are triggered by a device plugged in, button pressed, or time of day and you need one to wait but even then what one goes first. Can't quite wrap my head around this again after coming back to this again and again.
So to put the Wiki another way at least for my own future reference you do not need the Semaphore lock for subroutines as they will wait for each subroutine to complete before starting the next one. Here is a little modification to the Wiki that hopefuly helps someone.
Semaphore Actions (Lock, Unlock, and Reset)
The Semaphore Lock Action ensures that only one macro, or instance of a macro, is allowed to run at a time. This is especially useful when you want to prevent multiple instances of the same macro or different macros from executing simultaneously.
How It Works
To prevent simultaneous execution of macros, place a Semaphore Lock Action at the beginning of each macro you want to control. These macros should all use the same Semaphore Name. When one macro begins executing, the Semaphore Lock Action prevents any other macros with the same Semaphore Name from starting until the first macro finishes.
Once a macro completes, it automatically releases the lock, allowing the next macro in line (if triggered) to execute. This process follows a First In, First Out (FIFO) order, meaning the first macro that was triggered will execute first.
If another macro is triggered while the Semaphore Lock is in place, it will have to wait until the lock is released. This prevents simultaneous execution of macros that could cause conflicts.
How to Implement Semaphore Locks
- Place a Semaphore Lock Action at the start of each macro you wish to control.
- Ensure all these macros share the same Semaphore Name.
- The Semaphore remains locked until the macro finishes, and the next one in line will run when the lock is released.
Optional: Cancel Pending Macros
You can add a short timeout (e.g., 0.01 seconds) to the Semaphore Lock Action. This will cause any macro instances that can't acquire the lock within that brief period to cancel automatically, ensuring that no overlapping macros run.
Additional Notes
- A Semaphore Unlock Action is used to release the lock manually, but the Semaphore will also unlock automatically when the macro that triggered the lock completes.
- Use Semaphore Reset cautiously. It can forcibly unlock a semaphore, which is usually unnecessary and should be reserved for special cases.
Right now 200 of my 1000 macros use a semaphore lock.
You just listed several examples where semaphores are helpful. Allow me to give specific examples where I use them. Whenever I have macros that might press a keyboard key (or a mouse button), I place a semaphore like the following directly before the action in the macro that uses the keyboard (or mouse.) And usually I also follow the action that uses the keyboard or mouse with an "unlock semaphore" action. This is because some apps won't see both keys if they are pressed too closely together. In fact, depending on the app, sometimes I have to place a pause after the semaphore lock to ensure there is enough time between keys and clicks.
I also place semaphore lock actions at the top of nearly all my macros that are triggered with a Periodic Trigger, so that there cannot be two copies accidentally running simultaneously.
Keyboards and mice aren't the only "global resource" that a macro can try to access. For example, the "Speak" action is something I use a lot to report errors. If two macros are trying to report errors at the same time, it's much better for one to wait until the other has finished. So I do something like this:
Other actions which I like to prevent simultaneous occurrences are "Display Briefly", "Display Large", and "Notification."
Also, I like to use semaphore locks at the top of any macro that is triggered by a keyboard hotkey, to prevent accidental concurrent calls to the same macro.
-Example Macros Macros (v11.0.3)
-Example Macros Macros.kmmacros (82 KB)
Thank you that is a helpful stat to know. I am at just over 4,000 macros and it looks like I have them only on 54 and wasn't totally sure if I really needed them on them.
I thought tonight that some of the sound notification wasn't playing because I didn't have the Semaphore lock on but even with it the same issue happened with it playing one sound rather than toggling like It seems like it is supposed to.
-Example Macros Macros (v11.0.3)
-Example Macros Macros.kmmacros (82 KB)
I don't have an periodic triggers and perhaps I could use those in my life but haven't really thought of any use cases for me which is suprising with 4,000 macros haha and over 1,000 archived.
Interesting that is 95% of my macros and even the one included that is pretty complext with the spacebar after pressing on and of 8 times fast it always does things sequentially and I have never had a need have the lock but I might be mistaken because I certainly have had to put in delays in macros a lot as well as instance delays between actions (which I recently learned about). I am hoping that I have just missed something and can make things better with adding these more often.
Do you find yourself just always naming your Semaphore lock after the macro or just use the same name for all of them or at least the keyboard shortcut macros?
Sometimes I name them after the macro. Sometimes I just throw in a string of 40 random digits or characters, which is essentially a guarantee that I won't use the same name in another macro.
Haha I like it, I was kind of thinking that was fine to do as well. Thanks for saying that and helping me get my head wrapped around how it works even more. To be sure you only have that random string once in the macro you put it in and never need to copy it to another macro that might be a submacro right? The submacro can have it's own Semaphore lock (not sure why my brain is having a little bit of a hard time with these). Quickeys I think always did everything sequentially and you could never trigger macros simultneously which of course was a limitation of it as well.
<nit-pick>
Subsequent macros still "start". They then pause when execution reaches a set semaphore lock. So you do get simultaneous execution of macros, up until the lock section. (Whether a paused macro is still "executing" is probably best left to the philosophers ).
</nit-pick>
The "only allow one instance of a macro" is really a special case, albeit the one most commonly seen, and as you say in your post it's the timeout that does the business -- once the lock is set, subsequent instances (or even entirely different macros, if using that same lock) will
- Trigger
- Execute
- Pause
- Timeout
- Abort
The general use-case for a lock is "exclusivity". That can take many forms -- some examples might be
- multi-step manipulation of a KM Dictionary, when you don't want another macro also making changes at the same time
- actions aimed at the frontmost window -- you don't want another macro bringing a different app to the front
- "For Each" on the contents of a folder to which another macro also adds/removes files
- a network-intensive operation you want to get done quickly, and not held up with "periodic" macros checking unimportant web sites for updates
...and many, many more.
So...
Sure -- if it was needed!
Thank you, between all the comments I am starting to get my head wrapped around the several use case scenerios. I will search the forums for macros that need Semaphore locks and make sure I am using them when it is wise to do so and avoiding them if not needed.
Yes, and they count towards the 50 simultaneous macro limit.
Oh that's cool I didn't realize there was such a limit.
Yes, and I think there's also a limit of 50 "nested actions." Once you hit 50, I think all macros terminate.
There was one time that my macros were grabbing all my key and mouse controls, and I couldn't stop the KM Engine since I couldn't move my mouse or press any keys, but I remembered the 50 macro limit, so I just started a long-running macro 50 times, and the macro that was stealing all my keys and mouse controls just stopped! So I took advantage of the 50 macro limit.