rossubscriber和parfor一起用的时候,风味独特。
经测试,
在release mode的时候,parpool的正在启动的时候,rossubscriber会使用callback不断地读入信息,而一旦parpool成功开启(这个时间节点很重要),callback似乎就停止下来了不再读取新信息。所有数据更新停留在parpool成功开启的那个时间点。当然,这是在parpool语句放在rossubscriber语句之后,才可以发生的,若parpool语句在rossubscriber之前,则parpool在callback运行前开启完毕,callback根本没有机会读取新信息。
然而,当在debug mode的时候,这些问题不会发生。
由此,做出以下猜想:当parpool启动完毕的时候,两个core都被占用了并且变成忙的状态,因此没有剩余的计算资源供callback使用了。但是在debug mode的时候,core可以切换回空闲状态,因此有计算资源可供callback使用。
好,用这个思路来尝试解决这个问题。
1. 查阅matlab在debug mode下的相关配置信息,是否验证了我的猜想。好吧,查不到。。。
2. 在开启parpool的时候,开启少于系统最大数量的个数。例如,电脑是双核电脑,最大数量可以是2,但是我们现在只开启一个parpool(1),来看剩余的那个计算资源可否被使用到callback上。经测试,发现并没有帮上忙。。。
3. 既然2的方法不奏效,那么极有可能是,空闲的资源并不能被自动运用于robotic toolbox system的运算,那么尝试指定计算资源给robotoic toolbox system可不可以呢?
(1)使用batch job. 为了可以让callback在后台工作,将wrenchhandle = rossubscriber(‘robot/../../endpoint_state’,@wrenchCallback)语句放进wrench_callback_script里,然后在原文件中用job= batch(‘wrench_callback_script’)代替。实践发现,load(job,’wrenchhandle’)是非法的。rossubscriber对象不可以被load。。。可是不load似乎又没有在后台运行callback啊。。。改了这个之后比之前更糟糕。
(2)使用spmd. 估计会和parfor,parpool一样的结局。
4. 前面的方法都不奏效,那也可能的确不是parpool引发的问题。。。所以,直接用for来试试,将所有的并行计算改成for运算,发现问题依然存在!!!而且更严重,callback甚至根本不更新不读取新信息!!!说明,这并不是parpool造成的问题,必定是callback造成的问题。然而在debug mode依然是可以成功运行的。。。不知道该如何面对。用Ctrl-c来终止程序的时候,反而触发了callback读取了三两个新信息。。。好的,赶紧在mathwork里查询matlab里面的Ctrl-c的机制:为什么他可以触发callback?然后,找到了一个答案,网址是:http://www.mathworks.com/matlabcentral/answers/101348-why-is-ctrl-c-inconsistent-in-breaking-out-of-loops-in-matlab-7-0-r14
5. 在这个答案里,说明在每一个loop里面需要加入drawnow可以促使程序将计算队列里面的工作做完,怀着死马当活马医的心情,我在loop的end前添加一句“drawnow”,麻木地按下了运行键,发现可以成功运行了。
。
。
。
!!!可以成功运行了!!!目瞪口呆.jpg
再查询drawnow的帮助,看看它为什么可以解决我的问题:
help drawnow
drawnow Update figure windows and process callbacks
天都光嗮。。。这说明了,每一个细节都可能是珍贵的症状信息,可以指引你发现问题所在,帮助你查到解决方法,虽然很多时候都不是真正有用的症状信息,但是不要轻易放弃细节!
————————2016.4.20 的分割线——————————————-
————————2016.7.4发现的———————-
以下是可以正常实时读取数据的代码:
delete(gcp);
parpool(2);
while(){
parfor…
drawnow;
}
以前以为是有drawnow才可以让程序正常实时读取数据,但是后面发现,没有开启parpool的话,即使有drawnow, globalIndex也根本更新不了,实时数据一个也读取不到。如果开启了parpool,但是没有在循环内使用parfor的话,globalIndex只能在parpool启动时的那段时间得到更新,后面就不能继续更新了。。。
为什么只有parpool的开启可以让callback工作呢。。。