如何将参数传递给线程? [英] how to pass argument into threading?
问题描述
我想使用线程模块为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屋!