Coordinator and QueueRunner

See Threading and Queues for how to use threads and queues. For documentation on the Queue API, see Queues.

class tf.train.Coordinator

A coordinator for threads.

This class implements a simple mechanism to coordinate the termination of a set of threads.


# Create a coordinator.
coord = Coordinator()
# Start a number of threads, passing the coordinator to each of them.
...start thread 1...(coord, ...)
...start thread N...(coord, ...)
# Wait for all the threads to terminate.

Any of the threads can call coord.request_stop() to ask for all the threads to stop. To cooperate with the requests, each thread must check for coord.should_stop() on a regular basis. coord.should_stop() returns True as soon as coord.request_stop() has been called.

A typical thread running with a coordinator will do something like:

while not coord.should_stop(): some work...

Exception handling:

A thread can report an exception to the coordinator as part of the should_stop() call. The exception will be re-raised from the coord.join() call.

Thread code:

  while not coord.should_stop(): some work...
except Exception as e:

Main code:

  coord = Coordinator()
  # Start a number of threads, passing the coordinator to each of them.
  ...start thread 1...(coord, ...)
  ...start thread N...(coord, ...)
  # Wait for all the threads to terminate.
except Exception as e:
  ...exception that was passed to coord.request_stop()

To simplify the thread implementation, the Coordinator provides a context handler stop_on_exception() that automatically requests a stop if an exception is raised. Using the context handler the thread code above can be written as:

with coord.stop_on_exception():
  while not coord.should_stop(): some work...

Grace period for stopping:

After a thread has called coord.request_stop() the other threads have a fixed time to stop, this is called the 'stop grace period' and defaults to 2 minutes. If any of the threads is still alive after the grace period expires coord.join() raises a RuntimeException reporting the laggards.

  coord = Coordinator()
  # Start a number of threads, passing the coordinator to each of them.
  ...start thread 1...(coord, ...)
  ...start thread N...(coord, ...)
  # Wait for all the threads to terminate, give them 10s grace period
  coord.join(threads, stop_grace_period_secs=10)
except RuntimeException: of the threads took more than 10s to stop after request_stop()
  ...was called.
except Exception:
  ...exception that was passed to coord.request_stop()

tf.train.Coordinator.__init__(clean_stop_exception_types=None) {:#Coordinator.init}

Create a new Coordinator.

  • clean_stop_exception_types: Optional tuple of Exception types that should cause a clean stop of the coordinator. If an exception of one of these types is reported to request_stop(ex) the coordinator will behave as if request_stop(None) was called. Defaults to (tf.errors.OutOfRangeError,) which is used by input queues to signal the end of input. When feeding training data from a Python iterator it is common to add StopIteration to this list.


Clears the stop flag.

After this is called, calls to should_stop() will return False.

tf.train.Coordinator.join(threads=None, stop_grace_period_secs=120)

Wait for threads to terminate.

This call blocks until a set of threads have terminated. The set of thread is the union of the threads passed in the threads argument and the list of threads that registered with the coordinator by calling Coordinator.register_thread().

After the threads stop, if an exc_info was passed to request_stop, that exception is re-raised.

Grace period handling: When request_stop() is called, threads are given 'stop_grace_period_secs' seconds to terminate. If any of them is still alive after that period expires, a RuntimeError is raised. Note that if an exc_info was passed to request_stop() then it is raised instead of that RuntimeError.

  • threads: List of threading.Threads. The started threads to join in addition to the registered threads.
  • stop_grace_period_secs: Number of seconds given to threads to stop after request_stop() has been called.
  • RuntimeError: If any thread is still alive after request_stop() is called and the grace period expires.



If an exception has been passed to request_stop, this raises it.


Register a thread to join.

  • thread: A Python thread to join.


Request that the threads stop.

After this is called, calls to should_stop() will return True.

  • ex: Optional Exception, or Python exc_info tuple as returned by sys.exc_info(). If this is the first call to request_stop() the corresponding exception is recorded and re-raised from join().


Check if stop was requested.


True if a stop was requested.


Context manager to request stop when an Exception is raised.

Code that uses a coordinator must catch exceptions and pass them to the request_stop() method to stop the other threads managed by the coordinator.

This context handler simplifies the exception handling. Use it as follows:

with coord.stop_on_exception():
  # Any exception raised in the body of the with
  # clause is reported to the coordinator before terminating
  # the execution of the body.

This is completely equivalent to the slightly longer code:

exception Exception as ex:



Wait till the Coordinator is told to stop.

  • timeout: Float. Sleep for up to that many seconds waiting for should_stop() to become True.

True if the Coordinator is told stop, False if the timeout expired.

class tf.train.QueueRunner

Holds a list of enqueue operations for a queue, each to be run in a thread.

Queues are a convenient TensorFlow mechanism to compute tensors asynchronously using multiple threads. For example in the canonical 'Input Reader' setup one set of threads generates filenames in a queue; a second set of threads read records from the files, processes them, and enqueues tensors on a second queue; a third set of threads dequeues these input records to construct batches and runs them through training operations.

There are several delicate issues when running multiple threads that way: closing the queues in sequence as the input is exhausted, correctly catching and reporting exceptions, etc.

The QueueRunner, combined with the Coordinator, helps handle these issues.

tf.train.QueueRunner.__init__(queue=None, enqueue_ops=None, close_op=None, cancel_op=None, queue_closed_exception_types=None, queue_runner_def=None, import_scope=None) {:#QueueRunner.init}

Create a QueueRunner.

On construction the QueueRunner adds an op to close the queue. That op will be run if the enqueue ops raise exceptions.

When you later call the create_threads() method, the QueueRunner will create one thread for each op in enqueue_ops. Each thread will run its enqueue op in parallel with the other threads. The enqueue ops do not have to all be the same op, but it is expected that they all enqueue tensors in queue.

  • queue: A Queue.
  • enqueue_ops: List of enqueue ops to run in threads later.
  • close_op: Op to close the queue. Pending enqueue ops are preserved.
  • cancel_op: Op to close the queue and cancel pending enqueue ops.
  • queue_closed_exception_types: Optional tuple of Exception types that indicate that the queue has been closed when raised during an enqueue operation. Defaults to (tf.errors.OutOfRangeError,). Another common case includes (tf.errors.OutOfRangeError, tf.errors.CancelledError), when some of the enqueue ops may dequeue from other Queues.
  • queue_runner_def: Optional QueueRunnerDef protocol buffer. If specified, recreates the QueueRunner from its contents. queue_runner_def and the other arguments are mutually exclusive.
  • import_scope: Optional string. Name scope to add. Only used when initializing from protocol buffer.
  • ValueError: If both queue_runner_def and queue are both specified.
  • ValueError: If queue or enqueue_ops are not provided when not restoring from queue_runner_def.



tf.train.QueueRunner.create_threads(sess, coord=None, daemon=False, start=False)

Create threads to run the enqueue ops for the given session.

This method requires a session in which the graph was launched. It creates a list of threads, optionally starting them. There is one thread for each op passed in enqueue_ops.

The coord argument is an optional coordinator that the threads will use to terminate together and report exceptions. If a coordinator is given, this method starts an additional thread to close the queue when the coordinator requests a stop.

If previously created threads for the given session are still running, no new threads will be created.

  • sess: A Session.
  • coord: Optional Coordinator object for reporting errors and checking stop conditions.
  • daemon: Boolean. If True make the threads daemon threads.
  • start: Boolean. If True starts the threads. If False the caller must call the start() method of the returned threads.

A list of threads.



Exceptions raised but not handled by the QueueRunner threads.

Exceptions raised in queue runner threads are handled in one of two ways depending on whether or not a Coordinator was passed to create_threads():

  • With a Coordinator, exceptions are reported to the coordinator and forgotten by the QueueRunner.
  • Without a Coordinator, exceptions are captured by the QueueRunner and made available in this exceptions_raised property.

A list of Python Exception objects. The list is empty if no exception was captured. (No exceptions are captured when using a Coordinator.)

tf.train.QueueRunner.from_proto(queue_runner_def, import_scope=None)

Returns a QueueRunner object created from queue_runner_def.

The string name of the underlying Queue.




Converts this QueueRunner to a QueueRunnerDef protocol buffer.

  • export_scope: Optional string. Name scope to remove.

A QueueRunnerDef protocol buffer, or None if the Variable is not in the specified name scope.

class tf.train.LooperThread

A thread that runs code repeatedly, optionally on a timer.

This thread class is intended to be used with a Coordinator. It repeatedly runs code specified either as target and args or by the run_loop() method.

Before each run the thread checks if the coordinator has requested stop. In that case the looper thread terminates immediately.

If the code being run raises an exception, that exception is reported to the coordinator and the thread terminates. The coordinator will then request all the other threads it coordinates to stop.

You typically pass looper threads to the supervisor Join() method.

tf.train.LooperThread.__init__(coord, timer_interval_secs, target=None, args=None, kwargs=None) {:#LooperThread.init}

Create a LooperThread.

  • coord: A Coordinator.
  • timer_interval_secs: Time boundaries at which to call Run(), or None if it should be called back to back.
  • target: Optional callable object that will be executed in the thread.
  • args: Optional arguments to pass to target when calling it.
  • kwargs: Optional keyword arguments to pass to target when calling it.
  • ValueError: If one of the arguments is invalid.

tf.train.LooperThread.__repr__() {:#LooperThread.repr}


A boolean value indicating whether this thread is a daemon thread (True) or not (False).

This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when no alive non-daemon threads are left.



Thread identifier of this thread or None if it has not been started.

This is a nonzero integer. See the thread.get_ident() function. Thread identifiers may be recycled when a thread exits and another thread is created. The identifier is available even after the thread has exited.


Return whether the thread is alive.

This method returns True just before the run() method starts until just after the run() method terminates. The module function enumerate() returns a list of all alive threads.



Return whether the thread is alive.

This method returns True just before the run() method starts until just after the run() method terminates. The module function enumerate() returns a list of all alive threads.


Wait until the thread terminates.

This blocks the calling thread until the thread whose join() method is called terminates -- either normally or through an unhandled exception or until the optional timeout occurs.

When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call isAlive() after join() to decide whether a timeout happened -- if the thread is still alive, the join() call timed out.

When the timeout argument is not present or None, the operation will block until the thread terminates.

A thread can be join()ed many times.

join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.

tf.train.LooperThread.loop(coord, timer_interval_secs, target, args=None, kwargs=None)

Start a LooperThread that calls a function periodically.

If timer_interval_secs is None the thread calls target(args) repeatedly. Otherwise target(args) is called every timer_interval_secs seconds. The thread terminates when a stop of the coordinator is requested.

  • coord: A Coordinator.
  • timer_interval_secs: Number. Time boundaries at which to call target.
  • target: A callable object.
  • args: Optional arguments to pass to target when calling it.
  • kwargs: Optional keyword arguments to pass to target when calling it.

The started thread.

A string used for identification purposes only.

It has no semantics. Multiple threads may be given the same name. The initial name is set by the constructor.


Called at 'timer_interval_secs' boundaries.




Start the thread's activity.

It must be called at most once per thread object. It arranges for the object's run() method to be invoked in a separate thread of control.

This method will raise a RuntimeError if called more than once on the same thread object.


Called when the thread starts.


Called when the thread stops.

tf.train.add_queue_runner(qr, collection='queue_runners')

Adds a QueueRunner to a collection in the graph.

When building a complex model that uses many queues it is often difficult to gather all the queue runners that need to be run. This convenience function allows you to add a queue runner to a well known collection in the graph.

The companion method start_queue_runners() can be used to start threads for all the collected queue runners.

  • qr: A QueueRunner.
  • collection: A GraphKey specifying the graph collection to add the queue runner to. Defaults to GraphKeys.QUEUE_RUNNERS.

tf.train.start_queue_runners(sess=None, coord=None, daemon=True, start=True, collection='queue_runners')

Starts all queue runners collected in the graph.

This is a companion method to add_queue_runner(). It just starts threads for all queue runners collected in the graph. It returns the list of all threads.

  • sess: Session used to run the queue ops. Defaults to the default session.
  • coord: Optional Coordinator for coordinating the started threads.
  • daemon: Whether the threads should be marked as daemons, meaning they don't block program exit.
  • start: Set to False to only create the threads, not start them.
  • collection: A GraphKey specifying the graph collection to get the queue runners from. Defaults to GraphKeys.QUEUE_RUNNERS.

A list of threads.