0

Using Queue in combination with threading. It goes something like this:

import threading
import Queue

# Message sender
def msg_send(msg):
    # Relay packed message

# Thread loop
def thread_func(queue):
    while 1:
        # Read stdin
        # Parse
        # On error send error message with new ID   <-- ID
        # On OK put ratified message into queue
        queue.put(msg)

# Class with main loop
class SomeApplication(options):
    def __init__(self, options):
         self.option1 = ...

    def queue_process(self):
        if self.queue.empty()
            return
        while not self.queue.empty():
            # Process message
            # etc

        # Post process actions
        # Send message with new ID on occasion.     <--- ID

    def loop(self, queue):
         while self.run:
             # do stuff
             # Send message using ID                <--- ID
             self.queue_process()
             time.sleep(self.sleep_time)


def Main():
    queue  = Queue.Queue()   # New Queue

                             # Declare thread
    thread = threading.Thread(target = thread_func, args = (queue))
    thread.daemon = True     # Daemon
    thread.start()           # Start thread

    app = SomeClass(options) # New instance of SomeClass

    app.loop(queue)          # Main loop
    app.quit()               # Tidy up app things.
    quit(thread)             # Closing thread and tidying up.

Now, I would like to add a counter as message ID. As in:

 message = {
     'id'   : ++counter,
     'data' : data
 }

 msg = pack_message(message)
 msg_send(msg)

If message is a reply, I reuse request ID, else I use the counter to generate next ID. I would like it to be sequential as it then also serve as a messages sent counter.

I can add a global variable as counter and use it in msg_send(), but at the time that function is called, message is packed (with ID inside). Packing differ on contents, and sometimes re-packing is not done.

How can I serve both the thread, that reads incoming + send messages on occasion, and the class function with a common counter?

Is it OK to use a global variable? Is there a better way? Should I do something in the direction of:

def id_gen():
    id_gen.counter += 1
    return id_gen.counter

id_gen.counter = 0

Hrmf. This is awkwardly explained, hope you get what I mean.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Zimzalabim
  • 1,107
  • 1
  • 12
  • 22
  • 2
    Take a look at the thread-safe counter code over in this answer. http://stackoverflow.com/questions/1717393/is-this-simple-python-code-thread-safe Sharing an instance of that would be a very workable solution. Of course you pay a performance penalty by serializing access. – stephbu Dec 04 '13 at 20:40
  • @stephbu: Nice, that looks about right. *Know "Thanks" are frowned upon in comments, but in this case I'll leave one.* – Zimzalabim Dec 04 '13 at 20:55

1 Answers1

1

if i understand correctly you want global variable accessible in multiple threads. the problem with this is that you have to "protect" your variable from multiple accesses at a time, and thats something you can do with Monitor class, which varies a bit depending on which language you use and i think then global variable is pretty acceptable solution.

tms1337
  • 114
  • 5
  • 1
    Yes, I want a common thread safe counter, using Python. stephbu's comment below Q looks to fulfil the task. – Zimzalabim Dec 04 '13 at 20:57