Zimzalabim
Zimzalabim

Reputation: 1137

Counter across threads

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.

Upvotes: 0

Views: 422

Answers (1)

tms1337
tms1337

Reputation: 114

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.

Upvotes: 1

Related Questions