Python中线程之间的信令

Python中线程之间的信令,python,multithreading,celery,Python,Multithreading,Celery,我正在开发一个实时数据采集程序。我有一个while-True循环,在它里面,我生成了执行相对较小任务的线程(我通过HTTP查询第三方API,为了实现快速查询,我并行查询) 每个线程负责更新特定的数据系列。这可能需要2、3甚至5秒钟。但是,我的while-True循环生成线程的速度可能快于线程完成所需的时间。因此,我需要生成的线程等待它们以前的线程完成 一般来说,线程完成所需的时间是不可预测的,因为线程查询HTTP服务器 我在考虑为每个线程创建一个命名信号量,然后如果为特定系列生成的线程发现前一个

我正在开发一个实时数据采集程序。我有一个while-True循环,在它里面,我生成了执行相对较小任务的线程(我通过HTTP查询第三方API,为了实现快速查询,我并行查询)

每个线程负责更新特定的数据系列。这可能需要2、3甚至5秒钟。但是,我的while-True循环生成线程的速度可能快于线程完成所需的时间。因此,我需要生成的线程等待它们以前的线程完成

一般来说,线程完成所需的时间是不可预测的,因为线程查询HTTP服务器

我在考虑为每个线程创建一个命名信号量,然后如果为特定系列生成的线程发现前一个线程在同一系列上工作,它将等待

我能看到的唯一问题是线程可能积压

这里最好的解决方案是什么?我应该看看芹菜之类的东西吗?我目前正在使用线程模块


谢谢

不!看在上帝或聪明设计师的份上,请不要这样做!不要持续创建/生成/任何线程,并尝试对其进行微管理。线程池-在启动时创建一些线程,并向它们传递一个生产者-消费者队列,以等待代表这些HTTP任务的类实例。

否!看在上帝或聪明设计师的份上,请不要这样做!不要持续创建/生成/任何线程,并尝试对其进行微管理。Threadpool—在启动时创建一些线程,并向它们传递一个生产者-消费者队列,以等待代表这些HTTP任务的类实例。

您应该使用
queue.queue
。为每个系列创建一个队列,并创建一个线程来侦听该队列。每次需要读取序列时,将请求放入队列中。线程等待队列中的项目,它接收到的每个项目都会读取数据。

您应该使用
queue.queue
。为每个系列创建一个队列,并创建一个线程来侦听该队列。每次需要读取序列时,将请求放入队列中。线程等待队列中的项目,它接收到的每个项目都会读取数据。

如果每次查询返回时都要重新查询API,那么可以使用的另一个选项是类似Twisted()的异步框架。我是一个相对扭曲的初学者,所以可能有比这更好的方式扭曲你的任务-

from twisted.internet import reactor, defer
def simple_task():
    status = query_your_api()
    return status

def repeating_call(status):
    print(status)
    d = threads.deferToThread(simple_task)
    d.addCallback(repeating_call)

data_series = [data1, data2, data3]
for data in data_series:
    repeating_call('starting everything up')

reactor.run()

如果每次返回一个查询时都要重新查询API,那么可以使用另一个选项,即类似Twisted()的异步框架。我是一个相对扭曲的初学者,所以可能有比这更好的方式扭曲你的任务-

from twisted.internet import reactor, defer
def simple_task():
    status = query_your_api()
    return status

def repeating_call(status):
    print(status)
    d = threads.deferToThread(simple_task)
    d.addCallback(repeating_call)

data_series = [data1, data2, data3]
for data in data_series:
    repeating_call('starting everything up')

reactor.run()

如果任务是CPU受限的,那么由于GIL,使用线程不会给您带来性能上的好处。如果您有并行数据但没有队列,那么您就做错了。您应该让一些工作人员从一个队列中获取输入(即下载一个url),然后将结果(下载的数据)放入另一个队列。其他工作人员可以使用此队列进一步处理数据,以此类推。如果任务受CPU限制,则由于GIL,使用线程不会给您带来性能好处。如果您有并行数据但没有队列,则说明您做得不对。您应该让一些工作人员从一个队列中获取输入(即下载一个url),然后将结果(下载的数据)放入另一个队列。其他工作人员可以使用此队列进一步处理数据,等等。