Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将一些线程函数分组到Python中_Python_Multithreading_Grouping - Fatal编程技术网

将一些线程函数分组到Python中

将一些线程函数分组到Python中,python,multithreading,grouping,Python,Multithreading,Grouping,我有一些函数,我希望它们位于不同的线程组中。也就是说,我想让这些不同的线程组依次运行。我的示例代码如下所示: import threading from threading import Thread def func_a(): # do something here def func_b(): # do something here def func_c(): # do something here def func_d(): # do somethi

我有一些函数,我希望它们位于不同的线程组中。也就是说,我想让这些不同的线程组依次运行。我的示例代码如下所示:

import threading
from threading import Thread

def func_a():
    # do something here


def func_b():
    # do something here

def func_c():
    # do something here

def func_d():
    # do something here

thread_a = threading.Thread(target = func_a)
thread_b = threading.Thread(target = func_b)
thread_c = threading.Thread(target = func_c)
thread_d = threading.Thread(target = func_d)

thread_a.start()
thread_b.start()
thread_c.start()
thread_d.start()

thread_a.join()
thread_b.join()
thread_c.join()
thread_d.join()

我想做的很简单:把a
func\u a
func\u b
作为
threading\u group\u a
,也把
func\u c
func\u d
作为
threading\u group\u b
。然后先执行
threading\u group\u a
,然后执行
threading\u group\u b

您可以使用
池。这是将线程分组并为其分配单个任务的方法。然后将任务分配给池,而不是特定的线程。您有4个函数,但它们只做2件事。因此,您可以这样做:

from multiprocessing.pool import ThreadPool

def func_a(*args):
    print 1

def func_b(*args):
    print 2

pool = ThreadPool(3)

pool.map(func_a, range(2))
pool.map(func_b, range(2))

11

22
注意,我必须更改函数签名,因为
pool.map
将一些参数传递给函数。文档指定映射块,直到结果准备就绪,因此我们可以删除
.join()


更新:是的,你可以。假设你需要a+b一起执行。您可以将它们封装在第三个函数中,它所做的只是调用其他两个函数:

def ab(*args):
    func_a()
    func_b()
现在将
ab
函数传递给线程池。如果需要从函数返回值,则将返回值分配给列表并返回该列表


更新2:

from multiprocessing.pool import ThreadPool

def func_a():
    print 1

def func_b():
    print 2

def ab(*args):
    func_a()
    func_b()

pool = ThreadPool(3)
pool.map(ab, range(2))

有两个问题需要考虑:

  • 线程分组
  • 流量控制
  • 您可以采用手动方式,使用
    list
    s或
    tuple
    s对参数和线程本身进行分组,还可以手动控制流:

    from threading import Thread
    
    # Functions for group 1: with no arguments and different fucntions
    def func_a():
        print(1)
    
    def func_b():
        print(1)
    
    # Functions for group 2: with a single function but different arguments
    def func_c(i):
        print(i)
    
    # Functions for group 3: with different functions and arguments
    def func_d(i):
        print(i)
    
    def func_e(i):
        print(i)
    
    funs_1 = (func_a, func_b)
    args_2 = ((2,), (2,))
    funs_3 = (func_d, func_e)
    args_3 = ((3,), (3,))
    
    threads_1 = tuple(Thread(target=func             ) for func in funs_1)
    threads_2 = tuple(Thread(target=func_c, args=args) for args in args_2)
    threads_3 = tuple(Thread(target=func,   args=args) for func, args in zip(funs_3, args_3))
    
    for thread in threads_1:
        thread.start()
    
    for thread in threads_1:
        thread.join()
    
    for thread in threads_2:
        thread.start()
    
    for thread in threads_2:
        thread.join()
    
    for thread in threads_3:
        thread.start()
    
    for thread in threads_3:
        thread.join()
    
    或者使用池,该池允许您指定可以启动的并发线程的数量,并且还将处理该控件:

    from concurrent.futures import ThreadPoolExecutor
    
    # Functions for group 1: with no arguments and different fucntions
    def func_a():
        print(1)
    
    def func_b():
        print(1)
    
    # Functions for group 2: with a single function but different arguments
    def func_c(i):
        print(i)
    
    # Functions for group 3: with different functions and arguments
    def func_d(i):
        print(i)
    
    def func_e(i):
        print(i)
    
    funs_1 = (func_a, func_b)
    args_2 = ((2,), (2,))
    funs_3 = (func_d, func_e)
    args_3 = ((3,), (3,))
    
    with ThreadPoolExecutor(max_workers=5) as pool:
        futures_1 = tuple(pool.submit(func) for func in funs_1)
    
    with ThreadPoolExecutor(max_workers=5) as pool:
        futures_2 = tuple(pool.submit(func_c, *args) for args in args_2)
    
    with ThreadPoolExecutor(max_workers=5) as pool:
        futures_3 = tuple(pool.submit(func, *args) for func, args in zip(funs_3, args_3))
    

    with
    语句确保池在退出之前完成所有任务。您只需要调用
    ThreadPoolExecutor
    实例方法
    submit()
    作为第一个参数,
    目标
    关键字参数等价物以及其他位置参数和关键字参数将传递给函数,如
    线程
    中的
    args
    kwargs
    关键字参数
    concurrent.futures
    位于Python3的标准库中,并且已经为Python2.5+移植,您可能需要在
    thread\u c.start()
    thread\u d.start()之前使用
    thread\u a.join()
    thread\u d.start()
    执行
    sudo pip安装futures

    是否可以?或者你想要一种自动的方式来处理更多的线程?@RomanPerekhrest我不完全同意,有些情况下,你需要一些操作的结果才能处理其他操作。期货和池是解决这种情况的wya,在我看来,它们是一个非常合法的用例。@adrio,仅仅说期货和池是一个非常合法的用例是不够的,最好在实践中加以证明。你可以通过张贴适当的answer@RomanPerekhrest我正在发布答案。谢谢!但是我不太明白什么是
    args_1=((1,),(1,)
    args_2=((2,),(2,)
    ?这是否意味着我的函数的输出?如果是这样的话,情况是在执行之前我没有函数的输出。。。是否有其他方法将函数本身放入
    args
    而不是输出?谢谢!!它们是传递给函数的参数。我将它们存储在元组中以便进行迭代,但您可以查看第二组ThreadPoolExecutor方法的示例,其中我不使用元组存储。为了简化,我希望将my函数本身放入
    线程
    中的
    目标
    。是的。。我看到了你的第二个,但它仍然没有把整个功能作为目标。此外,我更愿意为此使用
    线程化
    模块。谢谢是的,我就是这么做的。我正在使用
    打印
    作为功能,您可以用您为功能指定的任何名称替换它。例如,如果您不需要传递任何参数,您可以为
    future\u 21=pool.submit(my\u func)
    替换
    future\u 21=pool.submit(my\u func,arg1,arg2,kwarg1=value1,kwarg2=value2)
    。。。有没有办法把我所有的功能都放进去?请注意,我的示例代码只是示例。我想做的是按顺序在不同的线程组中执行几个函数。@ryan9025您可以使用包装器函数来执行。我已经更新了我的答案谢谢!因此,我创建了一个变量
    pool=ThreadPool(ab)
    。但是
    pool.map
    部分呢?@ryan9025不,您应该创建一个池,并在池中传递所需的线程数。
    pool.map
    是将工作分配给线程的部分。所以,
    pool=ThreadPool(4)
    然后
    pool.map(func,range(num\u of\u迭代))
    。阅读文档中有关
    pool
    的更多信息好的,但现在它重新运行
    TypeError:“ThreadPool”对象不可调用