Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #99789

Re: python response slow when running external DLL

From Peter Otten <__peter__@web.de>
Newsgroups comp.lang.python
Subject Re: python response slow when running external DLL
Date 2015-12-01 12:01 +0100
Organization None
Message-ID <mailman.66.1448967701.14615.python-list@python.org> (permalink)
References (2 earlier) <f4cf8b4f-94e7-4d97-b144-65f59c20fbc1@googlegroups.com> <mailman.173.1448626828.20593.python-list@python.org> <d6c59a36-38ba-4f26-b949-18f2b226e7e3@googlegroups.com> <mailman.184.1448705627.20593.python-list@python.org> <3ec6a016-dae5-4986-b035-c1a8cd4dc3e7@googlegroups.com>

Show all headers | View raw


jfong@ms4.hinet.net wrote:

> Peter Otten at 2015/11/28 UTC+8 6:14:09PM wrote:
>> No, the point of both recipes is that tkinter operations are only ever
>> invoked from the main thread. The main thread has polling code that
>> repeatedly looks if there are results from the helper thread. As far I
>> understand the polling method has the structure
>> 
>> f():
>>    # did we get something back from the other thread?
>>    # a queue is used to avoid race conditions
>> 
>>    # if yes react.
>>    # var_status.set() goes here
>> 
>>    # reschedule f to run again in a few millisecs;
>>    # that's what after() does
> 
> Have no idea how the main thread poll on all those events (or it use a
> queue)? All I know now is that the main thread(mainloop()?) can be easily
> blocked by event handlers if the handler didn't run as a separate thread.
> 
>> >     .....
>> >     .....
>> >     #do the rest
>> >     var_status.set('Download...')
>> >     _thread.start_new_thread(td_download, ())  #must use threading
>> > 
>> > def td_download():
>> >     result = mydll.SayHello()
>> >     if result:
>> >         var_status.set("Download Fail at %s" % hex(result))
>> >         showerror('Romter', 'Download Fail')
>> >     else:
>> >         var_status.set('Download OK')
>> >         showinfo('Romter', 'Download OK')
>> 
>> As td_download() runs in the other thread the var_status.set() methods
>> are problematic.
> 
> No idea what kind of problem it will encounter. Can you explain?

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()

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.

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

python response slow when running external DLL jfong@ms4.hinet.net - 2015-11-26 23:51 -0800
  Re: python response slow when running external DLL Peter Otten <__peter__@web.de> - 2015-11-27 10:18 +0100
    Re: python response slow when running external DLL jfong@ms4.hinet.net - 2015-11-27 03:14 -0800
      Re: python response slow when running external DLL Peter Otten <__peter__@web.de> - 2015-11-27 13:20 +0100
        Re: python response slow when running external DLL jfong@ms4.hinet.net - 2015-11-27 23:37 -0800
          Re: python response slow when running external DLL Peter Otten <__peter__@web.de> - 2015-11-28 11:13 +0100
            Re: python response slow when running external DLL jfong@ms4.hinet.net - 2015-11-28 18:55 -0800
              Re: python response slow when running external DLL jfong@ms4.hinet.net - 2015-11-30 17:03 -0800
              Re: python response slow when running external DLL Peter Otten <__peter__@web.de> - 2015-12-01 12:01 +0100
                Re: python response slow when running external DLL jfong@ms4.hinet.net - 2015-12-01 19:58 -0800
          Re: python response slow when running external DLL Laura Creighton <lac@openend.se> - 2015-11-28 11:51 +0100
            Re: python response slow when running external DLL jfong@ms4.hinet.net - 2015-11-28 19:04 -0800
      Re: python response slow when running external DLL Laura Creighton <lac@openend.se> - 2015-11-27 13:49 +0100

csiph-web