使用MySQL表作为Python中的线程队列

时间:2014-09-26 11:17:37

标签: python mysql multithreading python-multithreading

我有一个带有queue表的数据库,新的条目会连续插入队列中。

我希望Python脚本尽可能快地执行队列,我想我需要一些线程代码才能这样做,像守护进程一样运行。

但我无法弄清楚如何将数据库用作队列。

我正在看这个例子:

import MySQLdb
from Queue import Queue
from threading import Thread

def do_stuff(q):
    while True:
        print q.get()
        q.task_done()

q = Queue(maxsize=0)
num_threads = 10

for i in range(num_threads):
    worker = Thread(target=do_stuff, args=(q,))
    worker.setDaemon(True)
    worker.start()

// TODO:  Use the DB
db = MySQLdb.connect(...)
cursor = db.cursor()
q = cursor.execute("SELECT * FROM queue")

for x in range(100):
    q.put(x)
q.join()

2 个答案:

答案 0 :(得分:3)

2个快点:

  1. 假设您正在使用cPython,GIL将有效 渲染线程无用,只允许1个线程通过 一次翻译。几个解决方法是:

    • Gevent[source]

        

      gevent是一个基于协程的Python网络库,它使用   greenlet在libev之上提供高级同步API   事件循环。

    • multiprocessing模块,可以生成多个进程 - 这是python中的真正并发。

    • concurrent.futures模块 - python 3中的新模块,可用于端口 python 2. [source]

        

      这是一个新的高级库,只能在“工作”级别运行,这意味着您不再需要大惊小怪   同步,或管理线程或进程。你只需指定一个   线程或进程池与一定数量的“工人”,提交
        工作,并整理结果。它是Python 3.2中的新功能,但却是一个端口   Python 2.6+可在http://code.google.com/p/pythonfutures处获得。

  2. 您可以使用MySQLdb的SSDictCursor()并执行fetchone()。这是一个流式游标,您可以在无限的while()循环中运行它以类似于队列:

    cur = MySQLdb.cursors.SSDictCursor()
    
    cur.execute(query)
    
    while True:
    
    row = cursor.fetchone()
    
    if not row : break # (or sleep()!)
    
    else: # other
    
    1. 说了这么多,我建议你看一下像celerymongodb这样的工具来模拟队列和工作人员。关系数据库不仅仅是针对那种工作而被削减,并且遭受不必要的碎片化。 Here's如果你想了解更多关于mysql中的碎片的话,那就是一个很好的来源。

答案 1 :(得分:1)

我不确定它是否是最佳解决方案,但我想到了一个主线程的结构,它读取数据并填充队列。一定要避免双重。也许通过使用增加数字的主键很容易检查。

工作者结构很好,但是在评论中提到:GIL会避免任何提升。但是如果你的“do_stuff”独立于脚本本身就可以使用多处理(例如,任务是图片,“do_stuff”是“旋转图片90°”)。 Afaik它没有受到GIL的影响

https://docs.python.org/2/library/subprocess.html可以获得一些关于此的信息。

PS:英语不是我的母语。