如何将参数传递给线程? [英] how to pass argument into threading?

查看:153
本文介绍了如何将参数传递给线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用线程模块为range(1,100)中的每个元素添加5, 观察哪个线程在哪个线程中. 我已经完成了几乎所有的代码,但是如何将参数传递给threading.Thread?

I want to add 5 for every element in range(1,100) with threading module, to watch which rusult is in which thread. I finished almost of the code,but how to pass argument into threading.Thread?

import threading,queue
x=range(1,100)
y=queue.Queue()
for i in x:
    y.put(i)

def myadd(x):
    print(x+5)


for i in range(5):
    print(threading.Thread.getName())
    threading.Thread(target=myadd,args=x).start() #it is wrong here
    y.join()

想想dano,现在可以了,为了以交互方式运行,我将其重写为:

Thinks to dano ,it is ok now ,in order to run in interactive way, i rewrite it as:

方法1:以交互方式运行.

method 1:run in interactive way.

from concurrent.futures import ThreadPoolExecutor
import threading
x = range(1, 100)

def myadd(x):
    print("Current thread: {}. Result: {}.".format(threading.current_thread(), x+5))

def run():
    t = ThreadPoolExecutor(max_workers=5)
    t.map(myadd, x)
    t.shutdown()
run()

方法2:

from concurrent.futures import ThreadPoolExecutor
import threading
x = range(1, 100)
def myadd(x):
    print("Current thread: {}. Result: {}.".format(threading.current_thread(), x+5))
def run():
    t = ThreadPoolExecutor(max_workers=5)
    t.map(myadd, x)
    t.shutdown()
if __name__=="__main__":
    run()

如果要向ThreadPoolExecutor中传递更多的参数,该怎么办? 我想使用多处理模块计算1 + 3、2 + 4、3 + 45直到100 + 102. 那么使用多处理模块的20 + 1,20 + 2,20 + 3到20 + 100呢?

What about if more args to be passed into ThreadPoolExecutor? I want to calculate 1+3, 2+4, 3+45 until 100+102 with multi-processing module. And what about 20+1,20+2,20+3 until 20+100 with multi-processing module?

from multiprocessing.pool import ThreadPool
do = ThreadPool(5)
def myadd(x,y):
    print(x+y)

do.apply(myadd,range(3,102),range(1,100))

如何解决?

推荐答案

您似乎正在尝试手动创建线程池,以便使用五个线程来累加全部100个结果.如果是这种情况,我建议为此使用multiprocessing.pool.ThreadPool:

It looks like you're trying to create a thread pool manually, so that five threads are used to add up all 100 results. If this is the case, I would recommend using multiprocessing.pool.ThreadPool for this:

from multiprocessing.pool import ThreadPool
import threading
import queue

x = range(1, 100)

def myadd(x):
    print("Current thread: {}. Result: {}.".format(
               threading.current_thread(), x+5))

t = ThreadPool(5)
t.map(myadd, x)
t.close()
t.join()

如果您使用的是Python 3.x,则可以使用 concurrent.futures.ThreadPoolExecutor 代替:

If you're using Python 3.x, you could use concurrent.futures.ThreadPoolExecutor instead:

from concurrent.futures import ThreadPoolExecutor
import threading

x = range(1, 100)

def myadd(x):
    print("Current thread: {}. Result: {}.".format(threading.current_thread(), x+5))

t = ThreadPoolExecutor(max_workers=5)
t.map(myadd, x)
t.shutdown()

我认为您的原始代码有两个问题.首先,您需要将元组传递给args关键字参数,而不是单个元素:

I think there are two issues with your original code. First, you need to pass a tuple to the args keyword argument, not a single element:

threading.Thread(target=myadd,args=(x,))

但是,您还试图将range(1,100)返回的整个列表(如果使用Python 3.x,则为range对象)传递给myadd,这并不是您真正想要做的.还不清楚您使用队列的目的.也许您打算将其传递给myadd?

However, you're also trying to pass the entire list (or range object, if using Python 3.x) returned by range(1,100) to myadd, which isn't really what you want to do. It's also not clear what you're using the queue for. Maybe you meant to pass that to myadd?

最后一点说明:Python使用全局解释器锁(GIL),它可以防止一个以上的线程同时使用CPU.这意味着在线程中执行受CPU约束的操作(如加法运算)不会在Python中提高性能,因为一次只能运行一个线程.因此,在Python中,最好使用多个进程来并行化CPU绑定的操作.通过将第一个示例中的ThreadPool替换为from mulitprocessing import Pool,可以使上面的代码使用多个进程.在第二个示例中,您将使用ProcessPoolExecutor而不是ThreadPoolExecutor.您可能还想将threading.current_thread()替换为os.getpid().

One final note: Python uses a Global Interpreter Lock (GIL), which prevents more than one thread from using the CPU at a time. This means that doing CPU-bound operations (like addition) in threads provides no performance boost in Python, since only one of the threads will ever run at a time. Therefore, In Python it's preferred to use the multiple processes to parallelize CPU-bound operations. You could make the above code use multiple processes by replacing the ThreadPool in the first example with from mulitprocessing import Pool. In the second example, you would use ProcessPoolExecutor instead of ThreadPoolExecutor. You would also probably want to replace threading.current_thread() with os.getpid().

这是处理有两个不同的参数要传递的情况的方法:

Here's how to handle the case where there are two different args to pass:

from multiprocessing.pool import ThreadPool

def myadd(x,y):
    print(x+y)

def do_myadd(x_and_y):
    return myadd(*x_and_y)

do = ThreadPool(5)    
do.map(do_myadd, zip(range(3, 102), range(1, 100)))

我们使用zip创建一个列表,在其中将范围内的每个变量配对在一起:

We use zip to create a list where we pair together each variable in the range:

[(3, 1), (4, 2), (5, 3), ...]

我们使用map对该列表中的每个元组调用do_myadd,而do_myadd使用元组扩展(*x_and_y)将元组扩展为两个单独的参数,并将其传递给myadd.

We use map to call do_myadd with each tuple in that list, and do_myadd uses tuple expansion (*x_and_y), to expand the tuple into two separate arguments, which get passed to myadd.

这篇关于如何将参数传递给线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆