移动测试基础 请教一个 python 多线程的自动化问题

chen · 2017年03月06日 · 最后由 hechang1994 回复于 2017年03月22日 · 1447 次阅读

threads = []

t1 = threading.Thread(target=device1)
threads.append(t1)
t2 = threading.Thread(target=device2)
threads.append(t2)

if name == 'main':

for t in threads:
t.start()
for t in threads:
t.join()
print('all end:%s' % ctime())

代码如上。

说明:device1 和 device2 函数是控制两个真实跑自动化的设备。
问题:我试了一下,发现不能两个设备不能同时跑自动化脚本。跑完第一个线程后,就一直挂起。想请教高手,是不是 python 解释器有个什么每次单线程执行。那这个多线程模块不能用在这种场景?
补充:想请教大家,你们是怎么控制多个设备同时执行自动化脚本的。

共收到 13 条回复 时间 点赞
chen #13 · 2017年03月06日 Author

脚本是部分。另外,复制到上面出了问题,不要管代码。

自己在项目中用到的多线程,同时控制线程数,仅供参考
class scaner(threading.Thread):
 tlist = [] # list of all current scanner threads
 maxthreads = 100 # max number of threads we’re allowing
 evnt = threading.Event() # event to signal OK to create more threads
 lck = threading.Lock() # lock to guard tlist

 def init(self, host):
  threading.Thread.init(self)
  self.host = host # checking ports on this host

 def run(self):
  #######################
  ### do your method
  #######################
  scaner.lck.acquire()
  scaner.tlist.remove(self)
  if len(scaner.tlist) == scaner.maxthreads - 1:
   scaner.evnt.set()
   scaner.evnt.clear()
  scaner.lck.release()

 def newthread(host):
  scaner.lck.acquire()
  sc = scaner(host)
  scaner.tlist.append(sc)
  scaner.lck.release()
  sc.start()

 newthread = staticmethod(newthread)

调用
for host in hosts:

 scaner.lck.acquire()
 if len(scaner.tlist) >= scaner.maxthreads:
   # too bad, need to wait until not at thread limit
  scaner.lck.release()
  scaner.evnt.wait()
 else:
  scaner.lck.release()
 scaner.newthread(host)

threads = []
t1 = threading.Thread(target=run)
threads.append(t1)
t2 = threading.Thread(target=run)
threads.append(t2)
for t in threads:
    t.setDaemon(True)
    t.start()
t.join()
chen 回复

如果按照上面代码运行的话,也没看出有问题,你确认一下 device1 或者 device2 在结束后是否返回

这里是你的代码

import time
import threading

def device1():
    for i in range(10):
        print('device1')
        time.sleep(1)

def device2():
    for i in range(10):
        print('device2')
        time.sleep(0.5)

threads = []

t1 = threading.Thread(target=device1)
threads.append(t1)

t2 = threading.Thread(target=device2)
threads.append(t2)

if __name__ == '__main__':
    for t in threads:
        print('start', t)
        t.start()

    for t in threads:
        print('join', t)
        t.join()

    print('all end')

这里是上面代码对应的打印

chen #5 · 2017年03月07日 Author
王华林 回复

非常感谢!问题找到了,程序没有问题,在进入 device1 和 device2 之前加了一个延时,就可以两个设备同时跑脚本了。我是把你那段打印加进去发现 ok 了,发现是需要延时。

chen #6 · 2017年03月07日 Author
Zhhh 回复

问题解决了,是需要加延时,不是代码错了

chen #7 · 2017年03月07日 Author
JoeJoe 回复

感谢,学习了

chen #8 · 2017年03月07日 Author
王华林 回复

我现在是问题解决了,但是不太明白多线程这块为啥会出现这样?device1 方法延时 10s,device2 方法延时 5s。两个设备同时执行脚本。不加就是不行。这是为什么?知道原因吗?

chen 回复

python 多线程本身与是否加延时没有什么关系的,我给你加延时是为了给你看到两个线程的执行过程。所以问题还是在于你的脚本执行的代码是怎么写的,你可以贴上一部分,不然大家想帮也帮不了你

如下不加延时的代码:

import threading

def device1():
    for i in range(10):
        print('device1')

def device2():
    for i in range(10):
        print('device2')

threads = []

t1 = threading.Thread(target=device1)
threads.append(t1)

t2 = threading.Thread(target=device2)
threads.append(t2)

if __name__ == '__main__':
    for t in threads:
        print('start', t)
        t.start()

    for t in threads:
        print('join', t)
        t.join()

    print('all end')

下面是对应的执行结果:

chen #4 · 2017年03月07日 Author
王华林 回复

def device2():

time.sleep(3)

device_id = '85GBBMA2333V'

device = MonkeyRunner.waitForConnection(10 ,device_id)
if not device:
print "NO device!"
else:
print "MeiZu Device connected!"

device.wake()

我感觉和 python 的处理机制有关,我用了三个机器试了一下,第一个方法可以不用延时,第二个要比第一个往后延时一定时间,第三个要比第二个延时一定时间。

因为用 windows 开三个 cmd 窗口,把执行方法分成三个单独的,并不需要延时就可以同时跑。

chen 回复

MonkeyRunner 这个支持同时初始化多个设备吗?你可以把 time.sleep()、device = MonkeyRunner.waitForConnection(10 ,device_id)、device.wake() 都注释掉,换上其他执行的过程,就可以看出差别。

chen #12 · 2017年03月07日 Author
王华林 回复

可能是 monkeyrunner 的问题,这个延时是用在连接设备这块了。延时至少 3s 后才能跑多个设备。你说注掉,注掉就找不到设备了。

device = MonkeyRunner.waitForConnection 这个是不能多线程的,需要连接后再用多线程

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册