当前位置: 首页 > 面试题库 >

限制一次运行的最大线程数的正确方法?

翟淇
2023-03-14
问题内容

我想创建一个运行多个轻线程的程序,但将其自身限制为恒定的,预定义数量的并发运行任务,如下所示(但不存在竞争条件的风险):

import threading

def f(arg):
    global running
    running += 1
    print("Spawned a thread. running=%s, arg=%s" % (running, arg))
    for i in range(100000):
        pass
    running -= 1
    print("Done")

running = 0
while True:
    if running < 8:
        arg = get_task()
        threading.Thread(target=f, args=[arg]).start()

最安全/最快的方法是什么?


问题答案:

听起来您想用8个工人实现生产者/消费者模式。PythonQueue为此提供了一个类,它是线程安全的。

每个工作人员都应调用get()队列以检索任务。如果没有可用的任务,此调用将阻塞,从而导致工作人员空闲直到可用。然后,工作人员应执行任务,最后task_done()在队列上进行调用。

您可以通过调用队列来将任务放入put()队列。

在主线程中,您可以调用join()队列以等待所有未完成的任务完成。

这种方法的好处是您无需创建和销毁线程,这很昂贵。工作线程将连续运行,但是当队列中没有任何任务时,将使用零CPU时间进入睡眠状态。

(链接的文档页面上有这种模式的示例。)



 类似资料:
  • 我有一个程序,把10个线程推到一个向量中,每个线程在完成之前要打印出一个字符5次(第一个线程是'a',第二个线程是'B',等等)。我可以让它们一次全部运行(使用detach())或者一次运行一个(使用join())。现在我想使用互斥体将一次允许打印的线程数限制为2。我已经能够声明互斥体并将锁放在适当的位置,但我不确定如何应用这样的限制。有人对如何继续有什么想法吗?

  • 问题内容: 以下代码假定可以创建100,000个线程: 它运行在具有32GB RAM的64位计算机上;已安装Debian 5.0,所有库存。 ulimit -s 512来减小堆栈大小 / proc / sys / kernel / pid_max设置为1,000,000(默认情况下,上限为32k pid)。 ulimit -u 1000000增加最大进程数(根本不认为这很重要) / proc /

  • 最小堆由 2047 个元素组成,确定最大元素数所需的最大比较数为 _。 对于这个,我使用了方法,因为这是一个最小堆,最小元素将在根节点中。所以要找到最大值,我们必须一直到树的末尾,直到叶节点级别,并且必须与所有值进行比较。所以比较将是n-1,但ans不是2046,而是1043。有人能给我解释一下吗?

  • 问题内容: 我有一个方法,可以写入数据库。要求是确保经过一定时间后该方法不执行。如果在此之前返回,则什么也不做。 我能想到的一种基本方法就是这样做。 这种方法的一个问题是,即使方法在最大总执行时间之前返回,程序也会暂停以等待经过的时间。 我该如何做得更好(或更正确)?如果使用,我们如何找出执行该方法的对象? 问题答案: 您可以通过将工作发送给执行者来做到这一点:

  • 问题内容: 我有要处理的网址列表,但我想一次运行最大数量的goroutine。例如,如果我有30个网址,那么我只希望10个goroutine并行工作。 我对此的尝试如下: 我的理解是,如果创建一个大小为并行的缓冲通道,那么该代码将阻塞,直到我读取结果通道为止,这将取消阻塞我的代码并允许生成另一个goroutine。但是,此代码似乎在处理完所有网址后不会阻塞。有人可以向我解释如何使用通道限制运行的g

  • 问题内容: Java虚拟机可以维护的最大线程数是多少? 我没有在最初的问题中对此进行解释,但是我正在尝试对JVM进行基准测试,并希望尝试查看它可以同时维护多少个线程。 在循环中创建线程直到引发异常是一种选择,但是,我想知道是否有更好的方法来执行此操作。 问题答案: 编写循环以创建新线程直到被炸毁是确定的明确方法。您可能会发现性能在实际消失之前会急剧下降。 我不知道JVM是否有任何配置参数或其他内置