<html><body>Hi 甜瓜,<br /><br />On 10:11 am, littlesweetmelon@gmail.com wrote:<br />>Q1: How to determine a function is 'blocking action' or not?<br />>Any function needs CPU times. Indeed, a computational-intensive<br />>function is blocking action. But how small/fast function can be<br />>classified as non-blocking? Twist requires all user functions to be<br />>non-blocked. If reactor calls a blocking function, what will happen?<br />>In my mind, reactor maintains a command queue internally (just like<br />>windows message queue). The blocking function only postpones the<br />>execution of other queued functions, but it does not break the logic<br />>of the program. Is that right?<br /><br />You've basically answered your own question here.  A "blocking action" is one where your users will not want to wait for it :).<br /><br />>Q2: Today when I go through the twist document, I am confused about<br />>the threading problem in reactor.<br />>What is the different between 'reactor.callFromThread' and a plain<br />>call in reactor loop?<br />>def callFromThread(f):<br />>            self.threadCallQueue.append((f, args, kw))<br />>            self.wakeUp()<br />>It seems equivalent to reactor.callLater(0, f...).<br />>What is the real circumstance for calling callFromThread?<br /><br />callLater is not thread-safe.  callFromThread is designed to be called, well, from a thread.  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 />>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.  There is no other way to determine if a function is thread-safe.  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 />>Why the twist doc says: "writing data to a transport from a protocol<br />>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 />>Q3: In my application, I need a facility to dynamically select a<br />>protocol to communicate with the server.<br />>Eg: When connected, the server sent a string to client to indicate the<br />>version of protocol it used. Then, the client can load the proper<br />>protocol. But I don't know how to implement this. A 'Factory' can only<br />>create one kind of 'Protocol', and it seems the instances of<br />>'Protocol' cannot share the connection (Transport object) to a server.<br />>Could you give me some clues?<br /><br />The protocol that you are implementing includes a "version" message.  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.  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>