Python - 传递参数时限制线程数

Python - Limiting the Number of Threads while passing arguments

我正在尝试 运行 一些线程使用线程限制器将线程数保持在 10 个。我有一个示例作为指导,但我需要在调用时将一些参数传递给函数线程。我正在为争论的传递而苦苦挣扎。我用### 标记了我不确定语法和我认为我的问题所在的地方。

我正在尝试使用此 The right way to limit maximum number of threads running at once? 作为指南。这是我尝试遵循的示例代码。我的例子在下面。每当我尝试传递所有参数时,我都会返回 TypeError: __ init__() takes 1 to 6 arguments but 17 were passed 在下面的示例中,我将参数减少到 4 以便于阅读,但我的实时代码中有 17 个参数。在示例中,我将参数缩小到 run, main_path, target_path, jiranum 以便于阅读

threadLimiter = threading.BoundedSemaphore(maximumNumberOfThreads)

class MyThread(threading.Thread):

def run(self):  
    threadLimiter.acquire()
    try:
        self.Executemycode()
    finally:
        threadLimiter.release()

def Executemycode(self):
    print(" Hello World!") 
    # <your code here>

我的代码

import os
import sys
import threading

threadLimiter = threading.BoundedSemaphore(10)

class MyThread(threading.Thread):

  def run(self):  ### I also tried (run, main_path, target_path, jiranum)
     threadLimiter.acquire()
     try:
       self.run_compare(run, main_path, target_path, jiranum) #### I also tried self
     finally:
       threadLimiter.release()

  def run_compare(run, main_path, target_path, jiranum):   #### ???
    os.chdir(target_path)
    os.system(main_path + ', ' + target_path + ',' + jiranum + ',' + run)

if __name__ == '__main__':
    #set the needed variables
    threads = []

    for i in range (1, int(run)+1):
       process=threading.Thread(target=MyThread, args=(str(i), main_path, target_path, jiranum)) #### Is this defined right?
       process.start()
       threads.append(process)

       for process in threads:
          process.join()
                       

concurrent.futures 这可能是一项更简单的任务,但我喜欢亲自动手,所以我们开始吧。几点建议:

  • 我发现 类 因为线程目标通常会使事情复杂化,所以如果没有令人信服的理由,请保持简单
  • 使用 with 块获取和释放信号量更容易,在这种情况下,常规信号量通常就足够了
  • 17 个参数可能会变得混乱;我会在调用 threading.Thread() 之外构建一个参数元组,这样更容易阅读,然后在线程
  • 中解压元组

这应该是一个简单的例子; os.system() 只是回显一些东西然后休眠,所以你可以看到线程数受信号量限制。

import os
import threading
from random import randint

threadLimiter = threading.Semaphore(10)

def run_config(*args):
    run, arg1, arg2 = args           # unpack the 17 args by name

    with threadLimiter:
        seconds = randint(2, 7)
        os.system(f"echo run {run}, args {arg1} {arg2} ; sleep {seconds}")

if __name__ == '__main__':
    threads = []
    run = "20"          # I guess this is a string because of below?

    for i in range (1, int(run)+1):
        thr_args = (str(i), "arg1",
                    "arg2")           # put the 17 args here
        thr = threading.Thread(target=run_config, args=thr_args)
        thr.start()
        threads.append(thr)

    for thr in threads:
        thr.join()