need some help with threading module...

Discussion in 'Python' started by chahnaz.ourzikene, Dec 26, 2004.

  1. Hi all,

    This is the first i post in this newsgroup, i hope my english is not too
    bad...
    Let's get straight to the point ! I have a little probleme using threads in
    my little training example :
    I wish to create two threads in my application, one thread (the subject)
    will increment a variable, and another thread (the controller) will print a
    message saying "i am waiting..." or someting like that, until the counter of
    the first thread reaches 10 or higher. It will query the first thread object
    about the value of that counter in a while loop until that counter reaches
    10 or higher...

    Here is the code i wrote (it doesn't work):

    from threading import *

    ####################################

    class Subject(object):


    def __init__(self) :

    self.counter = 0

    t = Timer(0.00001,self.doIteratingStuff)

    t.start()


    def incrementCounter(self,n=1) :

    self.counter = self.counter + n

    def doIteratingStuff(self) :

    for i in range(10) :

    self.incrementCounter(4)

    print "the counter is now", self.counter


    def count(self):

    return self.counter

    ####################################

    class Controller(object):

    def __init__(self, objectToControl) :

    self.controlled = objectToControl

    self.th = Thread(target = self.stopCounting)

    def start(self):

    self.th.start()


    def stopCounting(self):

    i = 0

    #while(1):

    for i in range(100000) :

    print "###############################> waiting... ", i

    i = i + 1

    if self.controlled.count() >= 10 :

    print "it is ten"

    return

    ####################################

    class Application (object) :

    def __init__(self) :

    pass

    def launch(self) :

    self.sub = Subject()

    self.control = Controller(self.sub)

    self.control.start()


    ####################################


    a = Application()

    a.launch()

    Of course, the indentations are lost since i copied this code from my emacs
    on linux, and then paste it on my outlook express (i don't have the net on
    linux :(...).

    The probleme with the code is that the controler thread never stops !!
    that's why the while loop is now commented and replaced by a for loop... I
    wish the problem is clear for all and that somebody can give some help !



    Thanks for all and merry x-mas and blablablah.

    Yacine Chaouche, France.
     
    chahnaz.ourzikene, Dec 26, 2004
    #1
    1. Advertising

  2. chahnaz.ourzikene

    M.E.Farmer Guest

    > Thanks for all and merry x-mas and blablablah
    There is no X in Christmas, and blablablah should read Happy New Year!

    >Of course, the indentations are lost since i copied this code from my

    emacs
    >on linux, and then paste it on my outlook express (i don't have the

    net on
    >linux :(...).


    I have had problems with whitespace being stripped before, but I just
    cannot understand WHY would you post KNOWING it was missing indents.
    Fix-it repost and maybe someone might help you.

    Hth,
    M.E.Farmer
     
    M.E.Farmer, Dec 26, 2004
    #2
    1. Advertising

  3. I think it is more suitable in this form...



    from threading import *

    ####################################

    class Subject(object):


    def __init__(self) :

    self.counter = 0

    t = Timer(0.00001,self.doIteratingStuff)

    t.start()


    def incrementCounter(self,n=1) :

    self.counter = self.counter + n

    def doIteratingStuff(self) :

    for i in range(10) :

    self.incrementCounter(4)

    print "the counter is now", self.counter


    def count(self):

    return self.counter

    ####################################

    class Controller(object):

    def __init__(self, objectToControl) :

    self.controlled = objectToControl

    self.th = Thread(target = self.stopCounting)

    def start(self):

    self.th.start()


    def stopCounting(self):

    i = 0

    #while(1):

    for i in range(100000) :

    print "###############################> waiting... ", i

    i = i + 1

    if self.controlled.count() >= 10 :

    print "it is ten"

    return

    ####################################

    class Application (object) :

    def __init__(self) :

    pass

    def launch(self) :

    self.sub = Subject()

    self.control = Controller(self.sub)

    self.control.start()


    ####################################


    a = Application()

    a.launch()



    Thanls for all.



    Yacine Chaouche, France.
     
    chahnaz.ourzikene, Dec 26, 2004
    #3
  4. chahnaz.ourzikene

    M.E.Farmer Guest

    Just a warning!
    Threads and newbies don't mix well,
    many pitfalls and hard to find bugs await you.
    I would avoid using threads if at all possible.

    Now we have all that over lets see some code.

    py> import threading
    py> class Test(threading.Thread):
    .... def run(self):
    .... x = 0
    .... while x < 10:
    .... print x
    .... x += 1
    .... print " Ending"
    Use it like this:
    py> Test().start()

    There are other ways to do this, but you need to do a web search on
    threading.py , there are many examples out there.
    hth,
    M.E.Farmer
     
    M.E.Farmer, Dec 26, 2004
    #4
  5. I found your object-oriented approach, while admirable, a little
    muddled. So rather than modify your code, I simply took the paragraph
    you wrote describing the scenario and wrote my own.[1]

    Instead of having the Controller query the Subject (not exactly
    plausible), I had it wait for a signal (threading.Event) as set by the
    Subject. You could also have it query a queue, as that is a generally
    accepted and thread-safe object to use, but for this purpose I chose an
    event and a global variable. (I'm aware that some would look down on
    this, but I didn't see a problem, as it was only modified by one thread
    amd printed by the other.)

    Daniel Bickett

    NOTES:

    [1] Google killed my whitespace (as spaces _and_ tabs...) in the
    previews, so I pasted it on Nopaste:
    http://rafb.net/paste/results/KilM6t70.html
     
    Daniel Bickett, Dec 26, 2004
    #5
  6. Hi everybody,

    "Daniel Bickett" <> a écrit dans le message de news:
    ...
    > Instead of having the Controller query the Subject (not exactly
    > plausible), I had it wait for a signal (threading.Event) as set by the
    > Subject. You could also have it query a queue, as that is a generally
    > accepted and thread-safe object to use, but for this purpose I chose an
    > event and a global variable. (I'm aware that some would look down on
    > this, but I didn't see a problem, as it was only modified by one thread
    > amd printed by the other.)
    >
    > Daniel Bickett


    Your approache is a little different, since the subject is responsible of
    emiting a signal/event to the controller. I wish to avoid this situation.
    The reason is that i want to write an application where the model (the
    system) is completely unaware of the view and the controller. This way, i
    could easily change the way the model and the view interact, while the code
    of the model remains unchanged. I don't know if this is possible, that's why
    i'm trying to solve this problem with threads ! and hope someone could help
    me :)

    Thanks to all.
     
    chahnaz.ourzikene, Dec 27, 2004
    #6
  7. "M.E.Farmer" <> a écrit dans le message de news:
    ...

    > Just a warning!
    > Threads and newbies don't mix well,
    > many pitfalls and hard to find bugs await you.
    > I would avoid using threads if at all possible.


    Indeed :). But how will i learn using threads if i avoid using them :) ??

    > Now we have all that over lets see some code.
    >
    > py> import threading
    > py> class Test(threading.Thread):
    > ... def run(self):
    > ... x = 0
    > ... while x < 10:
    > ... print x
    > ... x += 1
    > ... print " Ending"
    > Use it like this:
    > py> Test().start()


    Your example is interristing...somehow this is not exactly what i want to
    realise. I have exposed the problem in an earlier reply...

    Thank you all.

    Yacine Chaouche -- France.
     
    chahnaz.ourzikene, Dec 27, 2004
    #7
  8. chahnaz.ourzikene

    M.E.Farmer Guest

    chahnaz.ourzikene wrote:
    > "M.E.Farmer" <> a écrit dans le message de news:
    > ...
    >
    > > Just a warning!
    > > Threads and newbies don't mix well,
    > > many pitfalls and hard to find bugs await you.
    > > I would avoid using threads if at all possible.

    >
    > Indeed :). But how will i learn using threads if i avoid using them

    :) ??
    That was the point , you probably don't need them, and if so avoid
    them.
    If you want to learn how to use them , go for it!
    That is an excellent reason to mess with them, it was just a warning
    because you WILL be bitten by them, just a matter of time ;)

    > > Now we have all that over lets see some code.
    > >
    > > py> import threading
    > > py> class Test(threading.Thread):
    > > ... def run(self):
    > > ... x = 0
    > > ... while x < 10:
    > > ... print x
    > > ... x += 1
    > > ... print " Ending"
    > > Use it like this:
    > > py> Test().start()

    >
    > Your example is interristing...somehow this is not exactly what i

    want to
    > realise. I have exposed the problem in an earlier reply...
    > Yacine Chaouche -- France.


    I should have mentioned this was an attempt to show you how to make a
    thread 'exit' after it reached 10. You are having problems with the
    controller class, please look again at what I gave you this as an
    example. Did you run it?
    It was specific to your question. You were having problems making the
    controller exit.
    It should explain where you are lost, notice I inherit from Thread and
    not object, notice a much simpler way to write the thread ....
    You also mention the MVC pattern. If you are trying to implement MVC
    with threads you are going about it the wrong way ;)
    Hth,
    M.E.Farmer
     
    M.E.Farmer, Dec 27, 2004
    #8
  9. Hi,

    I fixed the code, it runs under Linux but not under windows 0_o ??! i guess
    windows and Linux do not handle threads the same way.

    However, i don't have the result i excpect.

    Please have a look here :

    ## In this little program, i'm trying to find a way to yield data from a
    thread within another
    ## thread, where both threads are NON-COOPERATIVE.
    ## To do so, i imagined an application launching two threads : a subject (to
    yield data from)
    ## and a controller that will try to yield data from the subject. The
    controller has a link
    ## with the subject, so he can call his methods and ask him to return the
    desired data.
    ##
    ## The problem is that it appears that on windows systems, this program
    idles and crashes after
    ## some seconds. On linux systems, this program runs but not the way i
    figured : the two threads
    ## seem not to run in parallel...
    ##
    ## Look at the controller code : his job is to call the subject's methode
    "count()" and compare
    ## the returned data to a threshold he's exepcting to reach. If the count
    method of the subject
    ## returns a number less than threshold, than the controller loop again (in
    a recursive function)
    ## until the subject's count method returns a number greater or equal to
    threshold or the recursive funtion
    ## runs "limit" times ( to avoid unlimited recursive calls ).
    ##
    ## Now look at the subject code : his only job is to increment a counter in
    a recursive methode.
    ## This counter is retrieved within the controller code via the count()
    methode of the subject.
    ## When that counter reaches "threshold" (defined in the controller), the
    controller returns.
    ##
    ## Execute the following code to see the result. You'll find someting like
    this under linux :
    ##
    ######> controller waiting... 0 loops
    ######> controller waiting... 1 loops
    ######> controller waiting... 2 loops
    ######> controller waiting... 3 loops
    ######> controller waiting... 4 loops
    ######> controller waiting... 5 loops
    ######> controller waiting... 6 loops
    ######> controller waiting... 7 loops
    ######> controller waiting... 8 loops
    ######> controller waiting... 9 loops
    ######> controller waiting... 10 loops
    ######> controller waiting... 11 loops
    ######> controller waiting... 12 loops
    ######> controller waiting... 13 loops
    ######> controller waiting... 14 loops
    ######> controller waiting... 15 loops
    ######> controller waiting... 16 loops
    ######> controller waiting... 17 loops
    ######> controller waiting... 18 loops
    ######> controller waiting... 19 loops
    ######> controller waiting... 20 loops
    ######> controller waiting... 21 loops
    ######> controller waiting... 22 loops
    ######> controller waiting... 23 loops
    ######> controller waiting... 24 loops
    ######> controller waiting... 25 loops
    ######> controller waiting... 26 loops
    ######> controller waiting... 27 loops
    ######> controller waiting... 28 loops
    ######> controller waiting... 29 loops
    ######> controller waiting... 30 loops
    ######> controller waiting... 31 loops
    ######> controller waiting... 32 loops
    ######> controller waiting... 33 loops
    ######> controller waiting... 34 loops
    ######> controller waiting... 35 loops
    ######> controller waiting... 36 loops
    ######> controller waiting... 37 loops
    ######> controller waiting... 38 loops
    ######> controller waiting... 39 loops
    ######> controller waiting... 40 loops
    ######> controller waiting... 41 loops
    ######> controller waiting... 42 loops
    ######> controller waiting... 43 loops
    ######> controller waiting... 44 loops
    ######> controller waiting... 45 loops
    ######> controller waiting... 46 loops
    ######> controller waiting... 47 loops
    ######> controller waiting... 48 loops
    ######> controller waiting... 49 loops
    ## controller : limit of recursive loops reached :
    ## threshold 20 never reached
    ## Subject : the counter is now 0
    ## Subject : the counter is now 1
    ## Subject : the counter is now 2
    ## Subject : the counter is now 3
    ## Subject : the counter is now 4
    ## Subject : the counter is now 5
    ## Subject : the counter is now 6
    ## Subject : the counter is now 7
    ## Subject : the counter is now 8
    ## Subject : the counter is now 9
    ## Subject : the counter is now 10
    ## Subject : the counter is now 11
    ## Subject : the counter is now 12
    ## Subject : the counter is now 13
    ## Subject : the counter is now 14
    ## Subject : the counter is now 15
    ## Subject : the counter is now 16
    ## Subject : the counter is now 17
    ## Subject : the counter is now 18
    ## Subject : the counter is now 19
    ## Subject : the counter is now 20
    ## Subject : the counter is now 21
    ## Subject : the counter is now 22
    ## Subject : the counter is now 23
    ## Subject : the counter is now 24
    ## Subject : the counter is now 25
    ## Subject : the counter is now 26
    ## Subject : the counter is now 27
    ## Subject : the counter is now 28
    ## Subject : the counter is now 29
    ## Subject : the counter is now 30
    ## Subject : the counter is now 31
    ## Subject : the counter is now 32
    ## Subject : the counter is now 33
    ## Subject : the counter is now 34
    ## Subject : the counter is now 35
    ## Subject : the counter is now 36
    ## Subject : the counter is now 37
    ## Subject : the counter is now 38
    ## Subject : the counter is now 39

    from threading import Thread
    ####################################
    class Subject(Thread):

    def __init__(self,loops = 100) :
    Thread.__init__(self)
    self.counter = 0
    self.recu_loops = 0
    self.loops=loops

    def run(self):
    self.doRecursiveStuff(self.loops)

    def incrementCounter(self,n=1) :
    self.counter = self.counter + n

    def doIteratingStuff(self, ntimes = 300) :
    for i in xrange(ntimes) :
    self.incrementCounter()
    print "Subject : the counter is now", self.counter

    def doRecursiveStuff(self,ntime = 80) :
    if self.recu_loops < ntime :
    print "Subject : the counter is now", self.counter
    self.incrementCounter()
    self.recu_loops = self.recu_loops + 1
    self.doRecursiveStuff(ntime)
    return

    def count(self):
    return self.counter
    ####################################
    class Controller(Thread):

    def __init__(self, objectToControl, limit=100, threshold=20) :
    Thread.__init__(self)
    self.controlled = objectToControl
    self.recursive_turns = 0
    self.limit= limit
    self.threshold = threshold

    def run(self):
    self.stopCounting()

    def stopCounting(self):
    if self.recursive_turns < self.limit :
    print "######> controller waiting... ", self.recursive_turns,
    "loops"
    self.recursive_turns = self.recursive_turns + 1
    if self.controlled.count() >= self.threshold :
    print "controller : threshold", self.threshold, "reached"
    return
    self.stopCounting()
    else :
    print "controller : limit of recursive loops reached :"
    print "threshold",self.threshold,"never reached"
    ####################################
    class Application (object) :

    def __init__(self) :
    pass

    def launch(self) :
    self.sub = Subject(loops=40)
    self.control = Controller(self.sub,limit=50,threshold=20)
    self.control.start()
    self.sub.start()
    ####################################
    a = Application()
    a.launch()
     
    chahnaz.ourzikene, Dec 30, 2004
    #9
  10. chahnaz.ourzikene

    M.E.Farmer Guest

    chahnaz.ourzikene wrote:
    > Hi,
    >
    > I fixed the code, it runs under Linux but not under windows 0_o ??! i

    guess
    > windows and Linux do not handle threads the same way.
    >
    > However, i don't have the result i excpect.

    What did you expect? This is what it did on win 2000/python 2.2.3
    ######> controller waiting... 0 loops
    ######> controller waiting... 1 loops
    Subject : the counter is now 0
    ######> controller waiting... 2 loops
    Subject : the counter is now 1
    ######> controller waiting... 3 loops
    Subject : the counter is now 2
    ######> controller waiting... 4 loops
    Subject : the counter is now 3
    Subject : the counter is now 4 ######> controller waiting... 5 loops

    Subject : the counter is now 5
    ######> controller waiting... 6 loops
    Subject : the counter is now 6
    ######> controller waiting... 7 loops
    Subject : the counter is now 7
    Subject : the counter is now 8
    ######> controller waiting... 8 loops
    Subject : the counter is now ######> controller waiting... 9 loops
    9
    Subject : the counter is now 10
    ######> controller waiting... 10 loops
    Subject : the counter is now 11
    Subject : the counter is now 12
    ######> controller waiting... 11 loops
    Subject : the counter is now 13
    ######> controller waiting... 12 loops
    Subject : the counter is now ######> controller waiting... 13 loops
    14
    Subject : the counter is now 15 ######> controller waiting... 14 loops

    Subject : the counter is now 16
    ######> controller waiting... 15 loops
    Subject : the counter is now 17
    ######> controller waiting... 16 loops
    Subject : the counter is now 18
    Subject : the counter is now 19
    ######> controller waiting... 17 loops
    Subject : the counter is now 20
    controller : threshold 20 reached
    Subject : the counter is now 21
    Subject : the counter is now 22
    Subject : the counter is now 23
    Subject : the counter is now 24
    Subject : the counter is now 25
    Subject : the counter is now 26
    Subject : the counter is now 27
    Subject : the counter is now 28
    Subject : the counter is now 29
    Subject : the counter is now 30
    Subject : the counter is now 31
    Subject : the counter is now 32
    Subject : the counter is now 33
    Subject : the counter is now 34
    Subject : the counter is now 35
    Subject : the counter is now 36
    Subject : the counter is now 37
    Subject : the counter is now 38
    Subject : the counter is now 39
    It seems to be what you were trying to do.

    M.E.Farmer
     
    M.E.Farmer, Dec 30, 2004
    #10
  11. chahnaz.ourzikene

    Steve Holden Guest

    M.E.Farmer wrote:

    > chahnaz.ourzikene wrote:
    >
    >>Hi,
    >>
    >>I fixed the code, it runs under Linux but not under windows 0_o ??! i

    >
    > guess
    >
    >>windows and Linux do not handle threads the same way.
    >>
    >>However, i don't have the result i excpect.

    >
    > What did you expect? This is what it did on win 2000/python 2.2.3
    > ######> controller waiting... 0 loops
    > ######> controller waiting... 1 loops
    > Subject : the counter is now 0

    [...]
    > Subject : the counter is now 38
    > Subject : the counter is now 39
    > It seems to be what you were trying to do.
    >

    Could be the OP is using Cygwin, which won't support threading by
    default and will give very confusing results

    just-a-guess-ly y'rs - steve
    --
    Steve Holden http://www.holdenweb.com/
    Python Web Programming http://pydish.holdenweb.com/
    Holden Web LLC +1 703 861 4237 +1 800 494 3119
     
    Steve Holden, Dec 30, 2004
    #11
  12. chahnaz.ourzikene

    M.E.Farmer Guest

    Steve Holden wrote:
    [snip]
    >Could be the OP is using Cygwin, which won't support threading by
    >default and will give very confusing results


    Thanks Steve,
    Well your guess was better then mine :)
    I didn't know Cygwin did not support threads by default , I will have
    to remember that.
    Why do you suppose he is having problems with this on Linux?
    I am not on a Linux box to test it.
    M.E.Farmer
     
    M.E.Farmer, Dec 30, 2004
    #12
  13. chahnaz.ourzikene

    Steve Holden Guest

    M.E.Farmer wrote:
    > Steve Holden wrote:
    > [snip]
    >
    >>Could be the OP is using Cygwin, which won't support threading by
    >>default and will give very confusing results

    >
    >
    > Thanks Steve,
    > Well your guess was better then mine :)
    > I didn't know Cygwin did not support threads by default , I will have
    > to remember that.
    > Why do you suppose he is having problems with this on Linux?
    > I am not on a Linux box to test it.
    > M.E.Farmer
    >

    I believe he said it runs under Linux but not under Windows. Since you
    (?) showed it does work under Windows, I guessed Cygwin.

    regards
    Steve
    --
    Steve Holden http://www.holdenweb.com/
    Python Web Programming http://pydish.holdenweb.com/
    Holden Web LLC +1 703 861 4237 +1 800 494 3119
     
    Steve Holden, Dec 30, 2004
    #13
  14. "M.E.Farmer" <> a écrit dans le message de news:
    ...

    > What did you expect? This is what it did on win 2000/python 2.2.3
    > ######> controller waiting... 0 loops
    > ######> controller waiting... 1 loops
    > Subject : the counter is now 0
    > ######> controller waiting... 2 loops
    > Subject : the counter is now 1
    >....
    >....
    >....


    Yeah, looking to the trace i can easily say you have executed it from IDLE,
    because IDLE is so slow that threads can have IRQs.
    Try to execute it directly from a shell under windows, and you will see that
    the Subject thread has much more CPU time thant the Controller thread.
    Because Subject does his job in a loop, and have no sleep call inside its
    code. Controller sleeps a while to let Subject run a little on the CPU.

    Now try to run it under Linux directly from the shell and you'll have much
    more time for Subject and very less for Controler. If you run it from IDLE
    it can be a little more parallel.

    Now there's a strange behaviour on my machine when i run my script within
    IDLE under Windows : IDLE idles and never stops runnig !! i ran the same
    script from a shell and it's all perfect...

    Very strange..

    Yacine Chaouche -- France

    > It seems to be what you were trying to do.
    >
    > M.E.Farmer
    >
     
    chahnaz.ourzikene, Dec 30, 2004
    #14
  15. "Steve Holden" <> a écrit dans le message de news:
    unYAd.64262$Jk5.31978@lakeread01...

    > Could be the OP is using Cygwin, which won't support threading by
    > default and will give very confusing results
    >
    > just-a-guess-ly y'rs - steve


    Nice try :), but nope :).

    Yacine Chaouche -- France.
     
    chahnaz.ourzikene, Dec 30, 2004
    #15
  16. chahnaz.ourzikene

    M.E.Farmer Guest

    Yacine,
    I didn't run it from Idle . I don't use Idle !
    I wrote my own IDE when I first started programming in Python, that is
    what I used(it does execute scripts from the shell ;)
    What you are seeing is exactly what I was talking about threads and..
    dare I say it... bugs .....
    Be sure to look at the post on c.l.py that were marked 'Problem in
    threading'.
    I am probably wrong , I am not a thread expert by any means, but I
    think that you are having a problem with the fact that threads can
    return out of order. Different OSes handle it differently. As always
    take it all with a grain of salt, and read more docs.
    Check into queue it is in the standard lib.
    By the way, I reread your post and still think that threads are not
    the way for you to go you really need to search for 'python MVC'. It
    may just enlighten you.
    M.E.Farmer
     
    M.E.Farmer, Dec 31, 2004
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Steve Menard
    Replies:
    7
    Views:
    532
    Dave Cole
    Jul 5, 2004
  2. Maric Michaud
    Replies:
    0
    Views:
    7,194
    Maric Michaud
    Jun 24, 2006
  3. Replies:
    9
    Views:
    1,048
    Mark Space
    Dec 29, 2007
  4. Steven Woody
    Replies:
    0
    Views:
    424
    Steven Woody
    Jan 9, 2009
  5. Steven Woody
    Replies:
    0
    Views:
    457
    Steven Woody
    Jan 9, 2009
Loading...

Share This Page