I used your product to overcome RSI injury from typing. Your product saved my butt! So grateful.
Anyhoo- I'm not a coder, and am having difficulty understanding the Semaphore Lock function.
Could you be so kind as to post the exact steps to take to prevent multiple macros from running simultaneously? I have read a few articles here, but can't seem to make it work. https://wiki.keyboardmaestro.com/action/Semaphore_Lock
The goal is to trigger a macro, then trigger another one, but this one waits for the previous to finish.
I'm not one of the elite superusers on this forum but I use semaphores in many of my macros to prevent duplicate executions. The simplest solution is just put this at the top of your macro, using any name in the field:
I usually use something similar to the name of my macro.
However this simple solution means that if you call it twice at roughly the same time, the first occurrence will complete, then the second occurrence will start up as soon as the first one has completed. This isn't always what you want. So here's what I usually do. I set a timeout value on the semaphore lock. Like this:
This way the second occurrence will not run at all, if it gets stuck waiting for more than one second.
I find that this solves most of my needs. For example, some of my macros can be invoked by either a timer or a function key. This prevents the timer one from starting up if I've already started it with function key.
The key is to use the same Semaphore Lock Name at the top of each of the Macro for which you want sequential execution. Then each Macro will wait until the previously triggered Macro has completed before it is executed.
Preventing Multiple Executions of One or More Macros
Occasionally there are cases where multiple macros can be triggered, or the same macro triggered again, before the other macros complete. This can sometimes cause a problem, which needs to be prevented.
The primary purpose of using a Semaphore Lock is to prevent simultaneous macro executions.
To do this, just place a Semaphore Lock Action with the same Semaphore Name as the first action of each Macro that you wish to prevent executing simultaneously.
The lock will remain in place preventing any other macros that try to execute until the first macro completes, or until you execute a Semaphore Unlock action.
Ah. This is ambiguous phrasing, as it can be interpreted—as I have been doing for the past year—to mean:
”Place a Semaphore Lock Action [in each macro that you wish to prevent executing simultaneously], and ensure that the Semaphore Name is the same as [the name of] the first action [in the macro].”
But now you’ve explained it, I can see it ought to be read as:
”Place a Semaphore Lock Action [in each macro that you wish to prevent executing simultaneously], making sure it is the first action [in the macro], and assign them all the same Semaphore Name [which can be anything].”
Yes. I'm sorry. I originally thought you meant two different copies of the same macro. It seems you mean two different macros. Your last post is the correct solution. Use the same semaphore name in each Macro that you want to protect them both from simultaneously running.
I presume we're all on the same page now, - no more ifs, ands or butts.
Thanks! I was replying to CJK's post #6 here, but given the chance I'll edit their text a bit more, and suggest
"If you want to prevent certain macros from executing simultaneously, place a Semaphore Lock Action as the first action in each one, and assign them all the same Semaphore Name. While a macro that begins with a Semaphore Lock Action is executing, no other macro that begins with a Semaphore Lock Action that has the same Semaphore Name will execute. If such a macro (or another instance of the first macro) is triggered, it will wait to execute until after the first macro ends, which automatically unlocks that semaphore."
This may be rather painstakingly detailed, and I'm sure it could be improved further, but I hope it's clearer to users like CJK and me?
Well that part's not always true. A semaphore can have a timeout and a flag that determines what happens when it times out. That statement is only true for the default configuration of a semaphore. I use timeouts on semaphores almost all the time, so that statement is almost never true for me.
Good catch, thanks! @JMichaelTX, let's make that line "it will wait to execute until the semaphore is unlocked" (unless that too has a problem I'm not seeing).
Heh, well, I'm actually a professional editor, so it would be awfully hypocritical of me to get bent out of shape when someone catches a problem in my writing! And certainly I want the wiki to be the best it can be