在Tensorflow的实际应用中,队列与线程是必不可少,主要应用于数据的加载等,不同的情况下使用不同的队列,主线程与其他线程异步进行数据的训练与读取,所以队列与线程的知识也是Tensorflow必须要学会的重要知识 另一方面,Tensorflow作为符号编程框架,在构图后,加载数据有三种方式,预加载与填充数据都存在,数据量大消耗内存等情况的出现.使用第三种方式文件读取避免了前两者的缺点,但是其实现则必须要使用队列与此线程,因此为了进一步的学习,也需要在这个时候掌握队列与线程的知识
运行结果
0.3 1.1 1.2运行结果:
1.0 6.0 3.0 0.0 7.0 4.0 8.0 9.0运行结果:
187.0 190.0 195.0 201.0 206.0 209.0 214.0 219.0 223.0 230.0 报错:......使用协调器来管理线程 这是要注意的的是在队列线程关闭后,再执行出队操作,将会报错”tf.errors.OutOfRange” 第一点会报错很好理解,队列关闭自然不能出队了(如果你学过数据结构那么你应该能够理解队列的意义,如果没能理解,建议重新掌握队列这一基本概念), 第二点则需要注意一下,报的错误是超出范围,而非队列不存在,希望当你遇到这个错误的时候能够想到,实际上可能是队列线程已经被取消了,而非真的超出了范围.
q = tf.FIFOQueue(1000, tf.float32) counter = tf.Variable(0.0) # 计数器 increment_op = tf.assign_add(counter, tf.constant(1.0)) # 操作给计数器加一 enquence_op = q.enqueue(counter) # 操作: 让计数器加入队列 # 第一种情况,在关闭其他线程之后(除主线程之外的其它线程),调用出队操作 print('第一种情况,在关闭其他线程之后(除主线程之外的其它线程),调用出队操作') # 创建一个队列管理器QueueRunner,用这两个操作相对列q中添加元素,目前我们只使用一个线程 qr = tf.train.QueueRunner(q, enqueue_ops=[increment_op, enquence_op] * 1) # 主线程 sess = tf.Session() sess.run(tf.global_variables_initializer()) # Coordinator: 协调器, 协调线程间的关系,可以视为一种信号量,用来做同步 coord = tf.train.Coordinator() # 启动入队线程,协调器是线程的参数 enqueue_threads = qr.create_threads(sess,coord=coord,start=True) # 主线程 for i in range(0,10): print(sess.run(q.dequeue())) coord.request_stop() # 通知其他线程关闭 coord.join(enqueue_threads) # join 操作等待其他线程结束,其他所有线程关闭之后,这一函数才能返回 print('第二种情况: 在队列线程关闭之后,调用出队操作-->处理tf.errors.OutOfRange错误') # q启动入队线程 enqueue_threads = qr.create_threads(sess,coord=coord,start=True) # 主线程 coord.request_stop() # 通知其他线程关闭 for j in range(0,10): try: print(sess.run(q.dequeue())) except tf.errors.OutOfRangeError: break coord.join(enqueue_threads) # join 操作等待其他线程结束,其他所有线程关闭之后,这一函数才能返回运行结果:
第一种情况,在关闭其他线程之后(除主线程之外的其它线程),调用出队操作 5.0 7.0 10.0 17.0 23.0 29.0 34.0 38.0 46.0 52.0 第二种情况: 在队列线程关闭之后,调用出队操作-->处理tf.errors.OutOfRange错误 53.0 53.0 53.0 53.0 53.0 53.0 53.0 53.0 53.0 53.0更详细的内容你可以参考github中的源代码
