python response slow when running external DLL

jfong at ms4.hinet.net jfong at ms4.hinet.net
Tue Dec 1 22:58:15 EST 2015


Peter Otten at 2015年12月1日 UTC+8 7:01:55PM wrote:
> While the var_status.set() invoked from the second thread modifies some 
> internal data the main thread could kick in and modify (parts of) that same 
> data, thus bringing tkinter into an broken state. A simple example that 
> demonstrates the problem:
>> import random
> import threading
> import time
>> account = 70
>> def withdraw(delay, amount):
> global account
> if account >= amount:
> print("withdrawing", amount)
> account -= amount
> else:
> print("failed to withdraw", amount)
>> threads = []
> for i in range(10):
> t = threading.Thread(
> target=withdraw,
> kwargs=dict(delay=.1,
> amount=random.randrange(1, 20)))
> threads.append(t)
> t.start()
>> for t in threads:
> t.join()

It's a simple and vivid example. You must be in the banking business:-)
In this exercise, I can just use update_idletasks() method to solve the deferred display problem of tkinter, and forget all about thread. But what if I really want to use thread for the long-running DLL function in the download hander? I didn't figure out a correct way of doing it at this moment. Maybe queue is the answer but I am not familiar with it yet.
def download():
 var_status.set(...) #showing a start-up message
 result = SayHello() #this is a long-running function
 if result.... #according to the result, display more messages
 ....
>> Before every withdrawal there seems to be a check that ensures that there is 
> enough money left, but when you run the script a few times you will still 
> sometimes end with a negative balance. That happens when thread A finds 
> enough money, then execution switches to thread B which also finds enough 
> money, then both threads perform a withdrawal -- oops there wasn't enough 
> money for both.
>> >> Another complication that inevitably comes with concurrency: what if the
> >> user triggers another download while one download is already running? If
> >> you don't keep track of all downloads the message will already switch to
> >> "Download OK" while one download is still running.
> > 
> > Hummm...this thought never comes to my mind. After take a quick test I
> > found, you are right, a second "download" was triggered immediately.
> > That's a shock to me. I suppose the same event shouldn't be triggered
> > again, or at least not triggered immediately, before its previous handler
> > was completed. ...I will take a check later on Borland C++ builder to see
> > how it reacts!
> > 
> > Anyway to prevent this happens? if Python didn't take care it for us.
>> A simple measure would be to disable the button until the download has 
> ended.

Good! simple and work.
I shouldn't say "Python should take care of it", but "tk" should do. It's annoying the widget's command was re-triggered before it was finished. (my personal opinion:-)


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /