While experimenting with asyncio.Event I noticed that calling the set/clear methods in close succession will awake all waiting tasks.
In fact running
import asyncio
async def waiter(event, seq):
print(f"A{seq}", end=" ")
await event.wait()
# surprise! event is not set in the statement following 'await event.wait()'
assert not event.is_set()
print(f"B{seq}", end=" ")
async def main():
event = asyncio.Event()
tset = set()
for i in range(10):
tset.add(asyncio.create_task(waiter(event, i)))
print("go A:", end=" ")
await asyncio.sleep(0)
print()
event.set()
event.clear()
print("go B:", end=" ")
await asyncio.sleep(0)
print()
for t in tset:
assert t.done()
asyncio.run(main())
will print
go A: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9
go B: B0 B1 B2 B3 B4 B5 B6 B7 B8 B9
The “surprise factor” here is that event.clear() will not undo the immediately preceding event.set(), even if control is not relinqushed to the event loop by the main coroutine.
However this behaviour makes prefectly sense account taken of the event loop implementation, and actually the docs state that after calling set()
All tasks waiting for event to be set will be immediately awakened.
But for clear() the docs say
Tasks awaiting on wait() will now block until the set() method is called again.
which is not 100% accurate, since only task which will execute await event.wait() in the next event loop run will block. Tasks that executed await event.wait() in the previous event loop run are not blocked again!
My question is therefore: is this intended asyncio.Event semantics or simply an event loop implementation detail which could change in the future?
The documentation is accurate.
As you quoted for set():
All tasks waiting for event to be set will be immediately awakened.
All tasks are immediately awakened, even if control is not relinquished to run them.
Source code: https://github.com/python/cpython/.../Lib/asyncio/locks.py#L181-L191
def set(self):
"""Set the internal flag to true. All coroutines waiting for it to
become true are awakened. Coroutine that call wait() once the flag is
true will not block at all.
"""
if not self._value:
self._value = True
for fut in self._waiters:
if not fut.done():
fut.set_result(True)
When clear() is called, there are no tasks awaiting on wait() anymore.
Related
I follow the reference document on Coroutine (https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html) and I test in the same time the example on Android Studio (a good boy).
But I am very confuse with cancelAndJoin() method.
If I replace, in the example code, the "cancelAndJoin" with "join", there is no difference in logs.
Here is the code :
fun main() = runBlocking {
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (i < 5) { // computation loop, just wastes CPU
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")
}
and in the 2 cases (with join or cancelAndJoin) the logs are :
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main: I'm tired of waiting!
job: I'm sleeping 3 ...
job: I'm sleeping 4 ...
main: Now I can quit.
Does anybody can explain what is the difference with the 2 methods?
This is not clear because cancel is "stopping the job", join is "waiting for completion", but the two together??? We "stop" and "wait"???
Thanks by advance :)
This is not clear because cancel is "stopping the job", join is
"waiting for completion", but the two together??? We "stop" and
"wait"?
Just because we wrote job.cancel() doesn't mean that job will cancel immediately.
When we write job.cancel() the job enters a transient cancelling state. This job is yet to enter the final cancelled state and only after the job enters the cancelled state it can be considered completely cancelled.
Observe how the state transition occurs,
When we call job.cancel() the cancellation procedure(transition from completing to cancelling) starts for the job. But we still need to wait, as the job is truly cancelled only when it reaches the cancelled state. Hence we write job.cancelAndJoin(), where cancel() starts the cancellation procedure for job and join() makes sure to wait until the job() has reached the cancelled state.
Make sure to check out this excellent article
Note: The image is shamelessly copied from the linked article itself
Ok I've just realize that my question was stupid!
cancelAndJoin() is equal to do cancel() and then join().
The code demonstrate that the job can not be cancelled if we don't check if it is active or not. And to do so, we must use "isActive".
So like this:
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (isActive) { // cancellable computation loop
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")
In a parallel application mimicking distributed inference, I would like to have an "initialization step" where all the "slaves" receive some initial information from the "master" then start their task.
At the moment I have a working implementation based on the sendTo function (the code was found here on stack overflow) but I don't think it guarantees that the worker won't start its task before it has received the initial objects.
Here's a rough MWE
function sendTo(p::Int; args...)
for (nm, val) in args
#spawnat(p, eval(Main, Expr(:(=), nm, val)))
end
end
a = 5
addprocs(4)
[sendTo(worker,a=a+randn()) for worker in workers()]
#everywhere begin
println(a)
end
The above "works" but how can I be sure that the commands in the #everywhere block does not get executed before the worker has received the definition of a?
Rmk: for the context I'm working in, I would like to keep two distinct blocks, one that spreads the data and one that does stuff on it.
Other rmk: apologies if this is trivial, I'm quite new to dealing with parallelism (and quite new to Julia too)
you can just fetch the results for every process. See the example in the docs
function sendTo(p::Int; args...)
r = []
for (nm, val) in args
s = #spawnat(p, eval(Main, Expr(:(=), nm, val)))
vcat([s],r)
end
end
#...
[fetch(r) for r in [sendTo(worker,a=a+randn()) for worker in workers()]]
I am converting the OCaml Format module to F# and tracked a problem back to a use of the OCaml Pervasives at_exit.
val at_exit : (unit -> unit) -> unit
Register the given function to be called at program termination time. The functions registered with at_exit will be called when the program executes exit, or terminates, either normally or because of an uncaught exception. The functions are called in "last in, first out" order: the function most recently added with at_exit is called first.
In the process of conversion I commented out the line as the compiler did not flag it as being needed and I was not expecting an event in the code.
I checked the FSharp.PowerPack.Compatibility.PervasivesModule for at_exit using VS Object Browser and found none.
I did find how to run code "at_exit"? and How do I write an exit handler for an F# application?
The OCaml line is
at_exit print_flush
with print_flush signature: val print_flush : (unit -> unit)
Also in looking at the use of it during a debug session of the OCaml code, it looks like at_exit is called both at the end of initialization and at the end of each use of a call to the module.
Any suggestions, hints on how to do this. This will be my first event in F#.
EDIT
Here is some of what I have learned about the Format module that should shed some light on the problem.
The Format module is a library of functions for basic pretty printer commands of simple OCaml values such as int, bool, string. The format module has commands like print_string, but also some commands to say put the next line in a bounded box, think new set of left and right margins. So one could write:
print_string "Hello"
or
open_box 0; print_string "<<";
open_box 0; print_string "p \/ q ==> r"; close_box();
print_string ">>"; close_box()
The commands such as open_box and print_string are handled by a loop that interprets the commands and then decides wither to print on the current line or advance to the next line. The commands are held in a queue and there is a state record to hold mutable values such as left and right margin.
The queue and state needs to be primed, which from debugging the test cases against working OCaml code appears to be done at the end of initialization of the module but before the first call is made to any function in the Format module. The queue and state is cleaned up and primed again for the next set of commands by the use of mechanisms for at_exit that recognize that the last matching frame for the initial call to the format modules has been removed thus triggering the call to at_exit which pushes out any remaining command in the queue and re-initializes the queue and state.
So the sequencing of the calls to print_flush is critical and appears to be at more than what the OCaml documentation states.
This should do it:
module Pervasives =
open System
open System.Threading
//
let mutable private exitFunctions : (unit -> unit) list = List.empty
//
let mutable private exitFunctionsExecutedFlag = 0
//
let private tryExecuteExitFunctions _ =
if Interlocked.CompareExchange (&exitFunctionsExecutedFlag, 1, 0) = 0 then
// Run the exit functions in last-in-first-out order.
exitFunctions
|> List.iter (fun f -> f ())
// Register handlers for events which fire when the process exits cleanly
// or due to an exception being thrown.
do
AppDomain.CurrentDomain.ProcessExit.Add tryExecuteExitFunctions
AppDomain.CurrentDomain.UnhandledException.Add tryExecuteExitFunctions
//
let at_exit f =
// TODO : This function should be re-written using atomic operations
// for thread-safety!
exitFunctions <- f :: exitFunctions
And some code to test it:
open System
// Register a couple of handlers to test our code.
Pervasives.at_exit <| fun () ->
Console.WriteLine "The first registered function has fired!"
Pervasives.at_exit <| fun () ->
Console.WriteLine "The second registered function has fired!"
TimeSpan.FromSeconds 1.0
|> System.Threading.Thread.Sleep
Console.WriteLine "Exiting the second registered function!"
Pervasives.at_exit <| fun () ->
Console.WriteLine "The third registered function has fired!"
// Do some stuff in our program
printfn "blah"
printfn "foo"
printfn "bar"
(* The functions we registered with at_exit should be fired here. *)
// Uncomment this to see that our handlers work even when the
// program crashes due to an unhandled exception.
//failwith "Uh oh!"
Sample code below. I'm a little curious why MyActor is faster than MyActor2. MyActor recursively calls process/react and keeps state in the function parameters whereas MyActor2 keeps state in vars. MyActor even has the extra overhead of tupling the state but still runs faster. I'm wondering if there is a good explanation for this or if maybe I'm doing something "wrong".
I realize the performance difference is not significant but the fact that it is there and consistent makes me curious what's going on here.
Ignoring the first two runs as warmup, I get:
MyActor:
559
511
544
529
vs.
MyActor2:
647
613
654
610
import scala.actors._
object Const {
val NUM = 100000
val NM1 = NUM - 1
}
trait Send[MessageType] {
def send(msg: MessageType)
}
// Test 1 using recursive calls to maintain state
abstract class StatefulTypedActor[MessageType, StateType](val initialState: StateType) extends Actor with Send[MessageType] {
def process(state: StateType, message: MessageType): StateType
def act = proc(initialState)
def send(message: MessageType) = {
this ! message
}
private def proc(state: StateType) {
react {
case msg: MessageType => proc(process(state, msg))
}
}
}
object MyActor extends StatefulTypedActor[Int, (Int, Long)]((0, 0)) {
override def process(state: (Int, Long), input: Int) = input match {
case 0 =>
(1, System.currentTimeMillis())
case input: Int =>
state match {
case (Const.NM1, start) =>
println((System.currentTimeMillis() - start))
(Const.NUM, start)
case (s, start) =>
(s + 1, start)
}
}
}
// Test 2 using vars to maintain state
object MyActor2 extends Actor with Send[Int] {
private var state = 0
private var strt = 0: Long
def send(message: Int) = {
this ! message
}
def act =
loop {
react {
case 0 =>
state = 1
strt = System.currentTimeMillis()
case input: Int =>
state match {
case Const.NM1 =>
println((System.currentTimeMillis() - strt))
state += 1
case s =>
state += 1
}
}
}
}
// main: Run testing
object TestActors {
def main(args: Array[String]): Unit = {
val a = MyActor
// val a = MyActor2
a.start()
testIt(a)
}
def testIt(a: Send[Int]) {
for (_ <- 0 to 5) {
for (i <- 0 to Const.NUM) {
a send i
}
}
}
}
EDIT: Based on Vasil's response, I removed the loop and tried it again. And then MyActor2 based on vars leapfrogged and now might be around 10% or so faster. So... lesson is: if you are confident that you won't end up with a stack overflowing backlog of messages, and you care to squeeze every little performance out... don't use loop and just call the act() method recursively.
Change for MyActor2:
override def act() =
react {
case 0 =>
state = 1
strt = System.currentTimeMillis()
act()
case input: Int =>
state match {
case Const.NM1 =>
println((System.currentTimeMillis() - strt))
state += 1
case s =>
state += 1
}
act()
}
Such results are caused with the specifics of your benchmark (a lot of small messages that fill the actor's mailbox quicker than it can handle them).
Generally, the workflow of react is following:
Actor scans the mailbox;
If it finds a message, it schedules the execution;
When the scheduling completes, or, when there're no messages in the mailbox, actor suspends (Actor.suspendException is thrown);
In the first case, when the handler finishes to process the message, execution proceeds straight to react method, and, as long as there're lots of messages in the mailbox, actor immediately schedules the next message to execute, and only after that suspends.
In the second case, loop schedules the execution of react in order to prevent a stack overflow (which might be your case with Actor #1, because tail recursion in process is not optimized), and thus, execution doesn't proceed to react immediately, as in the first case. That's where the millis are lost.
UPDATE (taken from here):
Using loop instead of recursive react
effectively doubles the number of
tasks that the thread pool has to
execute in order to accomplish the
same amount of work, which in turn
makes it so any overhead in the
scheduler is far more pronounced when
using loop.
Just a wild stab in the dark. It might be due to the exception thrown by react in order to evacuate the loop. Exception creation is quite heavy. However I don't know how often it do that, but that should be possible to check with a catch and a counter.
The overhead on your test depends heavily on the number of threads that are present (try using only one thread with scala -Dactors.corePoolSize=1!). I'm finding it difficult to figure out exactly where the difference arises; the only real difference is that in one case you use loop and in the other you do not. Loop does do fair bit of work, since it repeatedly creates function objects using "andThen" rather than iterating. I'm not sure whether this is enough to explain the difference, especially in light of the heavy usage by scala.actors.Scheduler$.impl and ExceptionBlob.
I have a system with two HID keyboards (actually, one's a barcode scanner.)
I registered for raw input with RIDEV_NOLEGACY to block the system from creating WM_KEY* messages for the barcode scanner, which tediously also blocks the messages from the other keyboard.
My goal is to keep the WM_* messages for any keybaord device that isn't the barcode scanner.
Basically, I need to either:
Create the WM_* messages myself, and post them to my hwnd from the wndproc that received the wm_input
or
Predict the WM_* messgaes the system will generate, and ignore them if they came from the barcode scanner.
I created a working implementation of 2, which works great on XP but fails to block anything on Windows 7. (In fact, on win7 it seems like i'm only reciving WM_INPUTs even without the RIDEV_NOLEGACY flag)
I'm now trying method 1, which is arguably 'more correct', but I can't seems to find a way to do this completely correctly.
My environment is Python 2.6 using PyQt. I'm sending messages directly to a window created by PyQt, and i've hooked into it's wndproc with a win32 event filter.
class wm_lparam(Structure):
_fields_ = [("repeat_count", c_short),
("scancode", c_byte),
("extended_key", c_int, 1),
("reserved", c_int, 4),
("context_code", c_int, 1),
("prev_state", c_int, 1),
("transition_state", c_int, 1),
]
assert sizeof(wm_lparam) == 8, sizeof(wm_lparam)
WM_KEYDOWN = 0x0100
WM_KEYUP = 0x0101
WM_SYSKEYDOWN = 0x0104
WM_SYSKEYUP = 0x0105
ALL_WM_KEYDOWN = (WM_KEYDOWN, WM_SYSKEYDOWN)
ALL_WM_KEYUP = (WM_KEYUP, WM_SYSKEYUP)
VK_SHIFT = 0x10
VK_LSHIFT = 0xA0
VK_RSHIFT = 0xA1
#These values are filled in by my WM_INPUT handler and the RAWINPUT struct
#staticmethod
def _synthesize_wm_legacy(hwnd, wm, vk, scancode, modifider_keys=None):
kbState_old = (c_byte*255)()
kbState = (c_byte*255)()
def keydown(vk):
return bool(user32.GetAsyncKeyState(vk) & 0x8000)
kbState[VK_SHIFT] = 0x80 if keydown(VK_SHIFT) else 0
kbState[VK_LSHIFT] = 0x80 if keydown(VK_SHIFT) else 0
user32.GetKeyboardState(kbState_old)
user32.SetKeyboardState(kbState)
lParam = wm_lparam()
lp = c_uint.from_address(ctypes.addressof(lParam))
lParam.repeat_count = 0
lParam.scancode = scancode
lParam.extended_key = 0
if wm in ALL_WM_KEYDOWN:
lParam.context_code = 0
lParam.prev_state = 0
lParam.transition_state = 0
if wm in ALL_WM_KEYUP:
lParam.repeat_count = 0
lParam.context_code = 0
lParam.prev_state = 1
lParam.transition_state = 1
lp = lp.value
if wm in ALL_WM_KEYUP: #Seems ctypes doesn't like my struct definition.
lp |= 1 << 30
lp |= 1 << 31
log.debug("Posting %s %s %s %08x\n%s"%(hwnd, wm_str(wm), vk, lp, lParam.dump_s()))
user32.SendMessageA(hwnd, wm, vk, lp)
user32.SetKeyboardState(kbState_old)
This code works, but certain things (like holding the shift key, etc) fail. Also very strange is that when using SendMessage, the letters I type are in uppercase, but switchign to PostMessage makes them lowercase. I can probably solve this via Get/SetKeyState, but I was hoping somebody could give me some answers.
In addition, I'm posting these messages back onto PyQt's queue, but the application fails to process them until a real event is sytem generated. That is, If I type a sentence into a text box, nothing shows up until I then move my mouse over the window. The messages seem queued until a real event happens. Any suggestions?
Clarification:
This is a window in my own process, created by PyQt. I have gotten it's hwnd, and hooked the raw input notification up to it. In the window procedure for WM_INPUT on this hwnd, I want to sendmessage to my own hwnd to duplicate the 'legacy' WM_KEY* messages that I previously disabled to filter them. Again, this all happens in my own process, in my own thread.
Update:
Shift state detection simply doesn't work. No matter what, I am getting all capital keys. Any advice?
I was unable to solve this in pure Win32, and I've gotten only a half solution since i'm using PyQt. In case anyone is interested though, here's the code i'm using for that portion:
class BarcodeQtEventFiler(QtCore.QObject):
def __init__(self, parent, *args):
self.log = logging.getLogger(__name__ + '.keyevent')
self.app = parent
self.input_to_surpress = list()
super(BarcodeQtEventFiler, self).__init__(parent, *args)
def ignoreKey(self, which):
"""On WM_INPUT from the device, call this with the reported VKey"""
self.input_to_surpress.append(which)
def eventFilter(self, object, event):
if event.type() == QtCore.QEvent.KeyPress:
if self.input_to_surpress:
if event.nativeVirtualKey() in self.input_to_surpress:
z = None
#This loop eats the suppression buffer until the VK pressed is found. Fixes Dupes for WM key up/down, etc.
while z != event.nativeVirtualKey():
z = self.input_to_surpress.pop(0)
self.log.debug("Ate key press %s (%s)", event.key(), event.text())
return True
else:
self.log.debug("Future surpressed input: %s", self.input_to_surpress)
self.log.debug("Allowing key press %s (%s)", event.key(), event.text())
return False
This is not fixable as-is, you cannot control the keyboard state. The receiving app will use GetKeyState() to check if the Shift, Ctrl or Alt key is down. SetKeyState() doesn't work, it only changes the keyboard state of your process, not the process that gets the messages.
Use SendInput() instead. A window in the target process must have the focus.