Threading Oddity?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kris Caselden

    Threading Oddity?

    I noticed a strange yet easily fixed problem in Python's thread
    module.

    Consider the following code:

    #-------------------------------

    import thread

    data='this is data'
    data_mutex = thread.allocate _lock()

    def thread1():
    while data_mutex.lock ed():
    data_mutex.aqui re()
    print 'thread1:',data
    if data_mutex.lock ed():
    data_mutex.rele ase()

    def thread2():
    while data_mutex.lock ed():
    data_mutex.aqui re()
    print 'thread2:',data
    if data_mutex.lock ed():
    data_mutex.rele ase()

    thread.start_ne w_thread(thread 1,())
    thread.start_ne w_thread(thread 2,())

    #-------------------------------

    This code runs as expected. However, take away the while loop checks
    for mutex lock and Python is unable to properly acquire the lock,
    complaining of an unhandled exception. The Python Library Reference
    mentions that "this method acquires the lock unconditionally , if
    necessary waiting until it is released by another thread (only one
    thread at a time can acquire a lock -- that's their reason for
    existence), and returns None." You'd think one wouldn't have to check
    if the lock is locked, especially when acquire is supposed to wait for
    the lock to be freed. At first, I thought this problem had to do with
    aquire()'s waitflag, but the problem exists regardless of waitflag's
    value.

    Does anyone know why this problem exists, and if my code works around
    it? It would seem that locked() and acquire() would not necessarily be
    run uninterrupted, and so mutual exclusion could not be guaranteed.
  • Kevin

    #2
    Re: Threading Oddity?

    use this instead and you're fine:

    import threading
    data_mutex = threading.Lock( )

    using the thread module directly is depreciated, and the threading.Lock( )
    object works as you expect without having to check if it's locked before
    acquiring it.

    Kevin




    "Kris Caselden" <google@hanger. snowbird.net> wrote in message
    news:abc3fdd3.0 308222033.78c46 0ab@posting.goo gle.com...[color=blue]
    > I noticed a strange yet easily fixed problem in Python's thread
    > module.
    >
    > Consider the following code:
    >
    > #-------------------------------
    >
    > import thread
    >
    > data='this is data'
    > data_mutex = thread.allocate _lock()
    >
    > def thread1():
    > while data_mutex.lock ed():
    > data_mutex.aqui re()
    > print 'thread1:',data
    > if data_mutex.lock ed():
    > data_mutex.rele ase()
    >
    > def thread2():
    > while data_mutex.lock ed():
    > data_mutex.aqui re()
    > print 'thread2:',data
    > if data_mutex.lock ed():
    > data_mutex.rele ase()
    >
    > thread.start_ne w_thread(thread 1,())
    > thread.start_ne w_thread(thread 2,())
    >
    > #-------------------------------
    >
    > This code runs as expected. However, take away the while loop checks
    > for mutex lock and Python is unable to properly acquire the lock,
    > complaining of an unhandled exception. The Python Library Reference
    > mentions that "this method acquires the lock unconditionally , if
    > necessary waiting until it is released by another thread (only one
    > thread at a time can acquire a lock -- that's their reason for
    > existence), and returns None." You'd think one wouldn't have to check
    > if the lock is locked, especially when acquire is supposed to wait for
    > the lock to be freed. At first, I thought this problem had to do with
    > aquire()'s waitflag, but the problem exists regardless of waitflag's
    > value.
    >
    > Does anyone know why this problem exists, and if my code works around
    > it? It would seem that locked() and acquire() would not necessarily be
    > run uninterrupted, and so mutual exclusion could not be guaranteed.[/color]


    Comment

    • Kevin

      #3
      Re: Threading Oddity?

      use this instead and you're fine:

      import threading
      data_mutex = threading.Lock( )

      using the thread module directly is depreciated, and the threading.Lock( )
      object works as you expect without having to check if it's locked before
      acquiring it.

      Kevin




      "Kris Caselden" <google@hanger. snowbird.net> wrote in message
      news:abc3fdd3.0 308222033.78c46 0ab@posting.goo gle.com...[color=blue]
      > I noticed a strange yet easily fixed problem in Python's thread
      > module.
      >
      > Consider the following code:
      >
      > #-------------------------------
      >
      > import thread
      >
      > data='this is data'
      > data_mutex = thread.allocate _lock()
      >
      > def thread1():
      > while data_mutex.lock ed():
      > data_mutex.aqui re()
      > print 'thread1:',data
      > if data_mutex.lock ed():
      > data_mutex.rele ase()
      >
      > def thread2():
      > while data_mutex.lock ed():
      > data_mutex.aqui re()
      > print 'thread2:',data
      > if data_mutex.lock ed():
      > data_mutex.rele ase()
      >
      > thread.start_ne w_thread(thread 1,())
      > thread.start_ne w_thread(thread 2,())
      >
      > #-------------------------------
      >
      > This code runs as expected. However, take away the while loop checks
      > for mutex lock and Python is unable to properly acquire the lock,
      > complaining of an unhandled exception. The Python Library Reference
      > mentions that "this method acquires the lock unconditionally , if
      > necessary waiting until it is released by another thread (only one
      > thread at a time can acquire a lock -- that's their reason for
      > existence), and returns None." You'd think one wouldn't have to check
      > if the lock is locked, especially when acquire is supposed to wait for
      > the lock to be freed. At first, I thought this problem had to do with
      > aquire()'s waitflag, but the problem exists regardless of waitflag's
      > value.
      >
      > Does anyone know why this problem exists, and if my code works around
      > it? It would seem that locked() and acquire() would not necessarily be
      > run uninterrupted, and so mutual exclusion could not be guaranteed.[/color]


      Comment

      • Christos TZOTZIOY Georgiou

        #4
        Re: Threading Oddity?

        On 22 Aug 2003 21:33:18 -0700, rumours say that
        google@hanger.s nowbird.net (Kris Caselden) might have written:

        [code snip][color=blue]
        >def thread1():
        > while data_mutex.lock ed():
        > data_mutex.aqui re()
        > print 'thread1:',data
        > if data_mutex.lock ed():
        > data_mutex.rele ase()[/color]
        [code snip]

        Kris, please copy-paste *real* code. This is not code you ran, this was
        written for the sake of the post. thread.lock object has no attribute
        "aquire".
        [color=blue]
        >This code runs as expected. However, take away the while loop checks
        >for mutex lock and Python is unable to properly acquire the lock,
        >complaining of an unhandled exception.[/color]

        I never had any problems with thread.lock.acq uire, and I use it a lot.
        Please come back with the code that fails for you, and specify the
        environment (OS, python version, whether you built it from sources, if
        you applied any changes to the source etc).

        The following program runs fine for me on Linux, Irix and Windows 2k:

        import thread, time

        data='this is data'
        data_mutex = thread.allocate _lock()

        def thread1():
        data_mutex.acqu ire()
        print 'thread1:',data
        data_mutex.rele ase()

        def thread2():
        data_mutex.acqu ire()
        print 'thread2:',data
        data_mutex.rele ase()

        thread.start_ne w_thread(thread 1,())
        thread.start_ne w_thread(thread 2,())
        time.sleep(1)

        I inserted the time.sleep(1) to allow for the threads to run before the
        program ends (and thus the threads end prematurely). threading would
        allow you to .join the threads instead.
        --
        TZOTZIOY, I speak England very best,
        Microsoft Security Alert: the Matrix began as open source.

        Comment

        • Christos TZOTZIOY Georgiou

          #5
          Re: Threading Oddity?

          On 22 Aug 2003 21:33:18 -0700, rumours say that
          google@hanger.s nowbird.net (Kris Caselden) might have written:

          [code snip][color=blue]
          >def thread1():
          > while data_mutex.lock ed():
          > data_mutex.aqui re()
          > print 'thread1:',data
          > if data_mutex.lock ed():
          > data_mutex.rele ase()[/color]
          [code snip]

          Kris, please copy-paste *real* code. This is not code you ran, this was
          written for the sake of the post. thread.lock object has no attribute
          "aquire".
          [color=blue]
          >This code runs as expected. However, take away the while loop checks
          >for mutex lock and Python is unable to properly acquire the lock,
          >complaining of an unhandled exception.[/color]

          I never had any problems with thread.lock.acq uire, and I use it a lot.
          Please come back with the code that fails for you, and specify the
          environment (OS, python version, whether you built it from sources, if
          you applied any changes to the source etc).

          The following program runs fine for me on Linux, Irix and Windows 2k:

          import thread, time

          data='this is data'
          data_mutex = thread.allocate _lock()

          def thread1():
          data_mutex.acqu ire()
          print 'thread1:',data
          data_mutex.rele ase()

          def thread2():
          data_mutex.acqu ire()
          print 'thread2:',data
          data_mutex.rele ase()

          thread.start_ne w_thread(thread 1,())
          thread.start_ne w_thread(thread 2,())
          time.sleep(1)

          I inserted the time.sleep(1) to allow for the threads to run before the
          program ends (and thus the threads end prematurely). threading would
          allow you to .join the threads instead.
          --
          TZOTZIOY, I speak England very best,
          Microsoft Security Alert: the Matrix began as open source.

          Comment

          • Kris Caselden

            #6
            Re: Threading Oddity?

            Christos "TZOTZIOY" Georgiou <tzot@sil-tec.gr> wrote in message news:<jrrekv4fo ls7tidfsnjkbc9m t56i54nhf2@4ax. com>...[color=blue]
            > Kris, please copy-paste *real* code. This is not code you ran, this was
            > written for the sake of the post. thread.lock object has no attribute
            > "aquire".[/color]

            You lost me for a second, until I realized that "aquire" and "acquire"
            are two different words ;) Sigh. However, my code does indeed run,
            without error, which begs the question; how is this working?

            Anyways, thanks for the fix.

            Comment

            • Kris Caselden

              #7
              Re: Threading Oddity?

              Christos "TZOTZIOY" Georgiou <tzot@sil-tec.gr> wrote in message news:<jrrekv4fo ls7tidfsnjkbc9m t56i54nhf2@4ax. com>...[color=blue]
              > Kris, please copy-paste *real* code. This is not code you ran, this was
              > written for the sake of the post. thread.lock object has no attribute
              > "aquire".[/color]

              You lost me for a second, until I realized that "aquire" and "acquire"
              are two different words ;) Sigh. However, my code does indeed run,
              without error, which begs the question; how is this working?

              Anyways, thanks for the fix.

              Comment

              • Christos TZOTZIOY Georgiou

                #8
                Re: Threading Oddity?

                On 23 Aug 2003 14:26:28 -0700, rumours say that
                google@hanger.s nowbird.net (Kris Caselden) might have written:
                [color=blue]
                >However, my code does indeed run,
                >without error, which begs the question; how is this working?[/color]

                Kris, I believe your code runs without error in your hardware, and I
                also know my code runs without error on my hardware. What your post
                initially implied is that /my/ code wouldn't run on /your/ hardware
                unless you wrapped the acquire calls in "while loop checks for mutex
                lock". Did you run my code successfully? If yes, we can skip that
                question as implicitly answered, if not, come back with more info.

                In your latest question, "how is this working?", do you mean how mutex
                locks work? The answer to this is that there are operating system calls
                whose purpose is to implement such locks, and Python builds on that. If
                I did not understand your question, please let me know.
                --
                TZOTZIOY, I speak England very best,
                Microsoft Security Alert: the Matrix began as open source.

                Comment

                • Jeff Epler

                  #9
                  Re: Threading Oddity?

                  On Fri, Aug 22, 2003 at 09:33:18PM -0700, Kris Caselden wrote:[color=blue]
                  > I noticed a strange yet easily fixed problem in Python's thread
                  > module.
                  >
                  > Consider the following code:
                  >
                  > #-------------------------------
                  >
                  > import thread
                  >
                  > data='this is data'
                  > data_mutex = thread.allocate _lock()
                  >
                  > def thread1():
                  > while data_mutex.lock ed():
                  > data_mutex.aqui re()
                  > print 'thread1:',data
                  > if data_mutex.lock ed():
                  > data_mutex.rele ase()
                  >
                  > def thread2():
                  > while data_mutex.lock ed():
                  > data_mutex.aqui re()
                  > print 'thread2:',data
                  > if data_mutex.lock ed():
                  > data_mutex.rele ase()
                  >
                  > thread.start_ne w_thread(thread 1,())
                  > thread.start_ne w_thread(thread 2,())[/color]

                  This code didn't run for me (no lines were printed) because the program
                  exits when the main thread is done. I added
                  import time
                  time.sleep(1)
                  after the start_new_threa d calls as a remedy. Then, it printed two
                  lines and waited about a second before I got the prompt back.

                  I tried removing the 'while's and dedenting the lines
                  "data_mutex.aqu ire". Then I got an attribute error!

                  But with the "while", there's no error. Why not? Because the mutex was
                  never locked! If the mutex is not locked, the body of the while statement
                  is not executed. On the other hand, if the statement inside the loop
                  was executed and did successfully claim the mutex, the 'while' condition
                  would evaluate to 'true' the next time through, the statement to claim
                  the lock would execute again, and block forever. (but this isn't likely
                  to happen on any particular run, because it would require that the mutex
                  be released at just the right moment.. properly testing threaded code is
                  hard)

                  I think this comes down to being a typo (as pointed out by another
                  poster, acquire vs aquire) and the addition of the 'while' loop just
                  adds confusion and is a completely wrong thing to do.

                  Jeff

                  Comment

                  Working...