Using asyncio in event-driven network library

Christian Gollwitzer auriocus at gmx.de
Wed Dec 25 14:52:45 CET 2013


Am 24.12.13 16:41, schrieb Tobias M.:
> On 23.12.2013 20:59, Terry Reedy wrote:
>> What would be easiest for user-developers would be if someone were
>> able to wrap a gui loop in a way to give it the needed interface, so
>> the gui loop itself replaced and became the asyncio loop.
>>
> That's a good idea, maybe I will try this. On the other hand this means
> that for every gui toolkit there must be a separate wrapper. I hoped this can
> be avoided.

To be done properly, it needs to be adapted for every toolkit. But the 
good news is, that it has already been achieved: IPython is able to 
integrate the readline library into all major GUI toolkits (%gui). Maybe 
you can rip off the code from there.

> On 23.12.2013 17:47, Chris Angelico wrote:
>> while gtk.events_pending(): gtk.main_iteration()
>>
>> No doubt other toolkits have something similar.
> On 23.12.2013 20:59, Terry Reedy wrote:
>> I think tk(inter) has 'run pending events' or something.

In Tk(inter) it is "update"

> I didn't know functions like this exist in gui toolkits. Am I right in
> thinking that using these functions you don't have to use the built-in
> event loop. Instead you can write your own loop and just call 'run
> pending events' continuously?

As Chris already explained, you then lose the advantages of the 
asynchronous operation. The reason behind the toolkits insisting on 
their main loop being run is, that they can wait for an event in a 
blocking way. Typically, under Linux, they call select() and on Windows 
WaitForMultipleObjects(), which blocks (sleeps) until an event arrives. 
Now to integrate your event source, you need to add it to this single 
blocking call.

Specifically, in the case of Tcl/Tk: The event loop is intrinsically 
able to wait for asynchronous IO from sockets, pipes, or serial lines to 
implement "fileevent". However, this is probably not useful since Python 
doesn't open files through Tcl's VFS layer. The easiest way is to run 
another thread, which waits in a blocking way, and to raise an event in 
the main thread. This is done from the C side by Tcl_ThreadQueueEvent() 
and Tcl_ThreadAlert() to wake up the event loop, or from the Tcl script 
level by the Threads package and sending a message to the main thread. 
Unfortunately this message queue stuff is quite complicated (it's 
described on the notifier man page 
http://www.tcl.tk/man/tcl/TclLib/Notifier.htm ). Further complication 
might come from the fact that some Linux distributions still ship with a 
Tcl that is not threads enabled. When I needed to add an unrelated event 
source, namely the events from GPIB devices, I simply used 
Tcl_AsyncProc() to do it, but I'm not sure whether this leads to race 
conditions.

	Christian



More information about the Python-list mailing list