<html><body>Hi 甜瓜,<br /><br />On 10:11 am, littlesweetmelon@gmail.com wrote:<br />&gt;Q1: How to determine a function is 'blocking action' or not?<br />&gt;Any function needs CPU times. Indeed, a computational-intensive<br />&gt;function is blocking action. But how small/fast function can be<br />&gt;classified as non-blocking? Twist requires all user functions to be<br />&gt;non-blocked. If reactor calls a blocking function, what will happen?<br />&gt;In my mind, reactor maintains a command queue internally (just like<br />&gt;windows message queue). The blocking function only postpones the<br />&gt;execution of other queued functions, but it does not break the logic<br />&gt;of the program. Is that right?<br /><br />You've basically answered your own question here. &#160;A "blocking action" is one where your users will not want to wait for it :).<br /><br />&gt;Q2: Today when I go through the twist document, I am confused about<br />&gt;the threading problem in reactor.<br />&gt;What is the different between 'reactor.callFromThread' and a plain<br />&gt;call in reactor loop?<br />&gt;def callFromThread(f):<br />&gt; &#160; &#160; &#160; &#160; &#160; &#160;self.threadCallQueue.append((f, args, kw))<br />&gt; &#160; &#160; &#160; &#160; &#160; &#160;self.wakeUp()<br />&gt;It seems equivalent to reactor.callLater(0, f...).<br />&gt;What is the real circumstance for calling callFromThread?<br /><br />callLater is not thread-safe. &#160;callFromThread is designed to be called, well, from a thread. &#160;You use callFromThread from threads *other* than the thread where the reactor is running, in order to wake up the reactor thread and have it do something - usually something that involves calling a non-thread-safe Twisted API.<br /><br />&gt;Further more, how to determine a function is thread-safe in python?<br /><br />As in any other language, ask the person who wrote it. &#160;There is no other way to determine if a function is thread-safe. &#160;In any language with dynamic run-time dispatch, determining this without talking to the author of the code in question reduces to the halting problem.<br /><br />&gt;Why the twist doc says: "writing data to a transport from a protocol<br />&gt;is not thread-safe."?<br /><br />Nothing in Twisted is thread-safe (other than callFromThread) but this is a particularly common error and we wanted to stress it.<br /><br />&gt;Q3: In my application, I need a facility to dynamically select a<br />&gt;protocol to communicate with the server.<br />&gt;Eg: When connected, the server sent a string to client to indicate the<br />&gt;version of protocol it used. Then, the client can load the proper<br />&gt;protocol. But I don't know how to implement this. A 'Factory' can only<br />&gt;create one kind of 'Protocol', and it seems the instances of<br />&gt;'Protocol' cannot share the connection (Transport object) to a server.<br />&gt;Could you give me some clues?<br /><br />The protocol that you are implementing includes a "version" message. &#160;Unless you have a "Protocol" object connected to receive the data and decode that message, you can't decide which version to use for subsequent messages. &#160;Simply implement a "Protocol" which understands that "version" message and changes its behavior accordingly.<br /><br />For an example of how you might switch to a completely different protocol object, see<br /><br />http://twistedmatrix.com/trac/browser/trunk/twisted/protocols/amp.py#L1524<br /><br />The techniques involved are quite nuanced, however, and are probably not appropriate for someone just learning about Twisted.<br /><br /></body></html>