首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python中的多线程和数组

Python中的多线程和数组
EN

Stack Overflow用户
提问于 2018-07-24 09:35:18
回答 3查看 4.3K关注 0票数 0

我目前正在对现有的脚本做一些修改,但问题是,我没有使用多线程的经验,我看到的例子越多,我就越困惑。

下面是我想要实现的一点洞察力。

脚本有两个输入,服务和动作,服务可以使用*来查找所有正在运行的服务,这使得服务成为一个存储在数组中的列表。

现在从好的方面来说,有一个基于服务和动作的函数,它执行一些事情,即

perform_service_action(service1, stop)

这将导致service1停止,依此类推。

不幸的是,这个过程被配置为按顺序运行,脚本处理时间太长,所以我想知道的是,你们中是否有人有任何关于如何处理这一点的提示,下面是代码的一小部分:

def main(argv):
    if len(argv) == 1:
        if argv[0] == 'list':
            list_of_serv = get_list(None)
            for service in list_of_serv:
                if not service == "":
                    print service
        else:
            help()
    elif len(argv) == 2:
        service_arg = argv[0]
        action = argv[1]
        list_of_serv = get_list(service_arg)
        for service in list_of_serv:
                perform_service_action(service, action)
        print_service_output()
    else:
        help()

我在这里和那里尝试了一些东西,但是我尝试得越多,我就越对线程这个主题感到困惑。这是仅仅改变代码的主要部分,以便在线程中运行具有不同值的相同函数吗?还是从头开始改变函数,这意味着获取列表的函数和对服务执行操作的函数。

我希望任何人都能在这方面给出一些建议。

提前谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-07-25 04:28:27

因此,在最后,我继续进行了更改,使用多线程而不是多处理,解决方案如下:

import threading



# For parallel execution
thread_limiter = threading.BoundedSemaphore(5)
thread_lock = threading.Lock()
thread_list = []

def main(argv):
if len(argv) == 1:
    if argv[0] == 'list':
        list_of_serv = get_list(None)
        for service in list_of_serv:
            if not service == "":
                print service
    else:
        help()
elif len(argv) == 2:
    service_arg = argv[0]
    action = argv[1]
    list_of_serv = get_list(service_arg)
    for service in list_of_serv:
        thread_limiter.acquire()
        thread = threading.Thread(target=perform_service_action, args=(service, action))
        thread.start()
        thread_list.append(thread)
        thread_limiter.release()
    [thread.join() for thread in thread_list]
    print_service_output()
else:
    help()

老实说,我把事情搞得太复杂了,但对于任何有类似问题的人,请随时以此为例。

感谢和问候在这篇文章中帮助我的每一个人。

票数 -2
EN

Stack Overflow用户

发布于 2018-07-24 10:24:25

您可以将您的代码更改为

 for service in list_of_serv:

    perform_service_action(service, action)

目标为:

 from multiprocessing import Pool
 from multiprocessing.dummy import Pool as ThreadPool

 pool.map(perform_service_action, zip( [service],[action]*len(service) ))

 pool.close()
 pool.join()

实际情况是,您可以创建映射到函数的池或进程

  perform_service_action

然后将可迭代(列表)传递给函数进行处理

如果您需要函数的结果,您还可以

result = pool.map(perform_service_action, zip( [service],[action]*len(service) ))

print (result ) 

这会给你一个所有结果的列表。

这应该有助于提高速度,但这也将取决于是否拥有所有用户输入或仅有数据。

票数 1
EN

Stack Overflow用户

发布于 2018-07-24 10:19:17

您最好为I/O繁重的操作选择multithreading,为CPU繁重的操作选择multiProcessing。因此,根据perform_service_action的功能,选择一个而不是另一个。

由于您的问题没有提供操作类型的清晰度,我将假定它的I/O很重。在Python中,gevents是我的用于并发的goto库。

在您的main()中,更改以下内容:

for service in list_of_serv:
            perform_service_action(service, action)

jobs = [gevent.spawn(perform_service_action, params) for service in list_of_serv]

这将产生多个线程(确切地说是greenlets)。为了并发地执行它们,

gevent.joinall(jobs, timeout=2)

您可以使用以下命令访问每个job的结果:

[job.value for job in jobs]

**请注意,在生成greenlets期间,您的参数将需要在perform_service_action方法中解包。(您可以使用*args或*kwargs,这取决于您希望如何实现它)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51489236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档