title: Python server: How can I continously queue tasks while making sure only one at a time is processed
body: <p>I have two tasks of which one is called every two seconds and the other one is called at random times. Both need to access an object that can't be called before the previous call is finished (if that happens I need to reboot the hardware device manually).</p>
  <p>The object is from a class which allows the communication with a hardware device via sockets.</p>
  <p>To do so I created a thread class, in order to run everything in the background and no other tasks are blocked. Within this class I implemented a queue: Two different functions put Tasks into the queue and a worker is supposed to execute the tasks !!NOT!! simultaneously.</p>
  <p>As this entire project is a server it should run continuously.</p>
  <p>Well here is my code and it obviously is not working. I would be very happy if anyone has a clue on how to solve this.</p>
  <p>Update: 26.10.2020
  In order to make my issue more clear I updated the code based on the answer from Artiom Kozyrev.</p>
  <pre><code>import time
  from threading import Lock, Thread
  import threading
  from queue import Queue
  
  
  class ThreadWorker(Thread):
      def __init__(self, _lock: Lock, _queue: Queue, name: str):
          # daemon=False means that process waits until all threads are finished
          # (not only main one and garbage collector)
          super().__init__(name=name, daemon=False)
          # lock prevents several worker threads do work simultaneously
          self.lock = _lock
          # tasks are send from the main thread via Queue
          self.queue = _queue
  
      def do_work(self, job):
          # lock context manager prevents other worker threads from working in the same time
          with self.lock:
              time.sleep(3)
              print(f&quot;{threading.current_thread().getName()}: {job * 10}&quot;)
  
      def run(self):
          while True:
              job = self.queue.get()
              # &quot;poison pillow&quot; - stop message from queue
              if not job:
                  break
              self.do_work(job)
  
  def TimeStamp(msg):
      tElapsed = (time.time() - tStart)  # Display Thread Info
      sElap = int(tElapsed)
      msElap = int((tElapsed - sElap) * 1000)
      usElap = int((tElapsed - sElap - msElap / 1000) * 1000000)
      print(msg , ': ',  sElap, 's', msElap, 'ms', usElap, 'us')
  
  def f1():
      TimeStamp(&quot;f1 start&quot;)
      time.sleep(2)
      TimeStamp(&quot;f1 finished&quot;)
  
  def f2():
      TimeStamp(&quot;f2 start&quot;)
      time.sleep(6)
      TimeStamp(&quot;f2 finished&quot;)
  
  def insertf1():
      for i in range(10):
          q.put(f1())
          time.sleep(2)
  
  def insertf2():
      for i in range(10):
          time.sleep(10)
          q.put(f2())
  
  
  
  q = Queue()
  lock = Lock()
  workers = [ThreadWorker(lock, q, f&quot;Th-worker-{i}&quot;) for i in range(5)]  # create workers
  for w in workers:
      w.start()
  
  tStart = time.time()
  threading.Thread(target=insertf1, daemon=True).start()
  threading.Thread(target=insertf2, daemon=True).start()
  </code></pre>
  <p>The output is:</p>
  <p>f1 start :  0 s 0 ms 0 us</p>
  <p>f1 finished :  2 s 2 ms 515 us</p>
  <p>f1 start :  4 s 9 ms 335 us</p>
  <p>f1 finished :  6 s 9 ms 932 us</p>
  <p>f1 start :  8 s 17 ms 428 us</p>
  <p>f2 start :  10 s 12 ms 794 us</p>
  <p>f1 finished :  10 s 28 ms 633 us</p>
  <p>f1 start :  12 s 29 ms 182 us</p>
  <p>f1 finished :  14 s 34 ms 411 us</p>
  <p>f2 finished :  16 s 19 ms 330 us</p>
  <p>f1 started before f2 was finished, which is what needs to be avoided.</p>