项目进程优化处理
Posted wudisanrenzu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了项目进程优化处理相关的知识,希望对你有一定的参考价值。
启用网络需在进程中启用,而和外面流程不相关,就出现信息更新滞后的情况,为此,做一些调查,将改变调用进程方式来实现。
l Handler
通过Handler你可以发布或者处理一个消息或者是一个Runnable的实例。没个Handler都会与唯一的一个线程以及该线程的消息队列管理。当你创建一个新的Handler时候,默认情况下,它将关联到创建它的这个线程和该线程的消息队列。也就是说,假如你通过Handler发布消息的话,消息将只会发送到与它关联的这个消息队列,当然也只能处理该消息队列中的消息。
主要的方法有:
1) public final boolean sendMessage(Message msg)
把消息放入该Handler所关联的消息队列,放置在所有当前时间前未被处理的消息后。
2) public void handleMessage(Message msg)
关联该消息队列的线程将通过调用Handler的handleMessage方法来接收和处理消息,通常需要子类化Handler来实现handleMessage。
l Looper
Looper扮演着一个Handler和消息队列之间通讯桥梁的角色。程序组件首先通过Handler把消息传送给Looper,Looper把消息放入队列。Looper也把消息队列里的消息广播给所有的Handler,Handler接受到消息后调用handleMessage进行处理。
1) 可以通过Looper类的静态方法Looper.myLooper得到当前线程的Looper实例,假如当前线程未关联一个Looper实例,该方法将返回空。
2) 可以通过静态方法Looper. getMainLooper方法得到主线程的Looper实例
线程,消息队列,Handler,Looper之间的关系可以通过一个图来展现:
在了解了消息队列及其相关组件的设计思想后,我们将把天气预告的案例通过消息队列来重新实现:
private EditText editText;
private Handler messageHandler;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editText = (EditText) findViewById(R.id.weather_city_edit);
Button button = (Button) findViewById(R.id.goQuery);
button.setOnClickListener(this);
//得到当前线程的Looper实例,由于当前线程是UI线程也可以通过Looper.getMainLooper()得到
Looper looper = Looper.myLooper();
//此处甚至可以不需要设置Looper,因为 Handler默认就使用当前线程的Looper
messageHandler = new MessageHandler(looper);
@Override
public void onClick(View v)
//创建一个子线程去做耗时的网络连接工作
new Thread()
@Override
public void run()
//活动用户输入的城市名称
String city = editText.getText().toString();
//调用Google 天气API查询指定城市的当日天气情况
String weather = getWetherByCity(city);
//创建一个Message对象,并把得到的天气信息赋值给Message对象
Message message = Message.obtain();
message.obj = weather;
//通过Handler发布携带有天气情况的消息
messageHandler.sendMessage(message);
.start();
//子类化一个Handler
class MessageHandler extends Handler
public MessageHandler(Looper looper)
super(looper);
@Override
public void handleMessage(Message msg)
//处理收到的消息,把天气信息显示在title上
setTitle((String) msg.obj);
Python多处理模块:加入超时进程
【中文标题】Python多处理模块:加入超时进程【英文标题】:Python multiprocessing module: join processes with timeout 【发布时间】:2014-11-21 17:16:21 【问题描述】:我正在优化复杂模拟的参数。我正在使用多处理模块来提高优化算法的性能。我在http://pymotw.com/2/multiprocessing/basics.html 学到的多处理基础知识。 根据优化算法的给定参数,复杂的模拟持续不同的时间,大约 1 到 5 分钟。如果参数选择得非常糟糕,模拟可能会持续 30 分钟或更长时间,并且结果没有用处。所以我正在考虑在多处理中建立一个超时,这会终止所有持续时间超过定义时间的模拟。这是问题的抽象版本:
import numpy as np
import time
import multiprocessing
def worker(num):
time.sleep(np.random.random()*20)
def main():
pnum = 10
procs = []
for i in range(pnum):
p = multiprocessing.Process(target=worker, args=(i,), name = ('process_' + str(i+1)))
procs.append(p)
p.start()
print('starting', p.name)
for p in procs:
p.join(5)
print('stopping', p.name)
if __name__ == "__main__":
main()
p.join(5)
行定义了 5 秒的超时。由于 for 循环 for p in procs:
程序等待 5 秒直到第一个进程完成,然后再等待 5 秒直到第二个进程完成等等,但我希望程序终止所有持续超过 5 秒的进程.此外,如果没有一个进程持续超过 5 秒,则程序不得等待这 5 秒。
【问题讨论】:
看看这里:***.com/q/1191374/2615940。它可能是重复的,但我不确定是否足以为您标记它。如果针对该答案的建议解决方案不适合您,请告诉我们原因。 这是一篇有趣的文章,但在我看来,它是连续启动进程而不是同时启动进程的解决方案。我的程序应该同时启动进程并杀死那些超过“全局”超时的进程。 【参考方案1】:感谢dano的帮助,我找到了解决办法:
import numpy as np
import time
import multiprocessing
def worker(num):
time.sleep(np.random.random()*20)
def main():
pnum = 10
TIMEOUT = 5
procs = []
bool_list = [True]*pnum
for i in range(pnum):
p = multiprocessing.Process(target=worker, args=(i,), name = ('process_' + str(i+1)))
procs.append(p)
p.start()
print('starting', p.name)
start = time.time()
while time.time() - start <= TIMEOUT:
for i in range(pnum):
bool_list[i] = procs[i].is_alive()
print(bool_list)
if np.any(bool_list):
time.sleep(.1)
else:
break
else:
print("timed out, killing all processes")
for p in procs:
p.terminate()
for p in procs:
print('stopping', p.name,'=', p.is_alive())
p.join()
if __name__ == "__main__":
main()
这不是最优雅的方式,我相信有比使用bool_list
更好的方式。超时 5 秒后仍处于活动状态的进程将被杀死。如果您在工作函数中设置的时间比超时时间更短,您将看到程序在达到 5 秒的超时时间之前停止。如果有的话,我仍然愿意接受更优雅的解决方案:)
【讨论】:
【参考方案2】:如果你想杀死所有进程,你可以使用多处理池 您需要为所有执行定义一个一般超时,而不是单独的超时。
import numpy as np
import time
from multiprocessing import Pool
def worker(num):
xtime = np.random.random()*20
time.sleep(xtime)
return xtime
def main():
pnum = 10
pool = Pool()
args = range(pnum)
pool_result = pool.map_async(worker, args)
# wait 5 minutes for every worker to finish
pool_result.wait(timeout=300)
# once the timeout has finished we can try to get the results
if pool_result.ready():
print(pool_result.get(timeout=1))
if __name__ == "__main__":
main()
这将为您提供一个列表,其中包含所有工作人员的返回值。 更多信息在这里: https://docs.python.org/2/library/multiprocessing.html#module-multiprocessing.pool
【讨论】:
我不认为这实际上会终止池中的线程——它只是将执行返回给主线程,即使它们没有完成 我不明白我们为什么要做pool_result.get(timeout=1)
即:如果pool_result 已经准备好了,结果不应该也准备好了,并且不需要超时吗?【参考方案3】:
您可以通过创建一个循环来执行此操作,该循环将等待一些超时秒数,并经常检查所有进程是否已完成。如果它们没有在分配的时间内全部完成,则终止所有进程:
TIMEOUT = 5
start = time.time()
while time.time() - start <= TIMEOUT:
if not any(p.is_alive() for p in procs):
# All the processes are done, break now.
break
time.sleep(.1) # Just to avoid hogging the CPU
else:
# We only enter this if we didn't 'break' above.
print("timed out, killing all processes")
for p in procs:
p.terminate()
p.join()
【讨论】:
谢谢,这似乎是一个合适的解决方案。不幸的是,如果进程在达到超时之前完成,则此代码不会中断。我通过将工作函数设置为time.sleep(1)
进行了尝试,1 秒后所有p.is_alive()
返回False
。所以代码现在应该转到break
语句,但它仍在等待超时...
我发现了问题:print (p.is_alive() for p in procs)
返回<generator object <genexpr> at 0x05712B20>
但它应该是一个包含True
或False
元素的列表,以便any()
可以理解
@brp 使用any([p.is_alive() for p in procs])
。这样它就变成了列表推导而不是生成器表达式。
@brp 哦,我刚刚注意到您使用的是np.any
,而不是内置的any
。这就是生成器表达式不起作用的原因。 np.any
仅适用于类数组对象。
内置 any
与列表理解是关键!谢谢!以上是关于项目进程优化处理的主要内容,如果未能解决你的问题,请参考以下文章
Android性能优化第(八)篇---App启动速度优化之耗时检测处理