我目前正在对现有的脚本做一些修改,但问题是,我没有使用多线程的经验,我看到的例子越多,我就越困惑。
下面是我想要实现的一点洞察力。
脚本有两个输入,服务和动作,服务可以使用*
来查找所有正在运行的服务,这使得服务成为一个存储在数组中的列表。
现在从好的方面来说,有一个基于服务和动作的函数,它执行一些事情,即
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()
我在这里和那里尝试了一些东西,但是我尝试得越多,我就越对线程这个主题感到困惑。这是仅仅改变代码的主要部分,以便在线程中运行具有不同值的相同函数吗?还是从头开始改变函数,这意味着获取列表的函数和对服务执行操作的函数。
我希望任何人都能在这方面给出一些建议。
提前谢谢。
发布于 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()
老实说,我把事情搞得太复杂了,但对于任何有类似问题的人,请随时以此为例。
感谢和问候在这篇文章中帮助我的每一个人。
发布于 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 )
这会给你一个所有结果的列表。
这应该有助于提高速度,但这也将取决于是否拥有所有用户输入或仅有数据。
发布于 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,这取决于您希望如何实现它)
https://stackoverflow.com/questions/51489236
复制相似问题