python多线程读取文件内容_python多线程读取logcat内容,导致其他线程阻塞
问题描述
背景:
通过adb读取安卓设备上的数据内容,包括logcat日志以及其他系统文件内容。实现方式是在python中启动多线程,每个线程中通过popen执行系统命令,如adb logcat -s tag:*,或者adb shell cat /proc/stat。
读取文件在communicate中等待返回结果,logcat由于是不断滚动输出,因此从流中逐行读取,即stdout.readline()
问题描述:
在实际运行中发现,logcat的popen会阻塞其他读取文件的popen;但logcat的线程中sleep 1秒后,再启动其他线程,则没有阻塞现象
相关代码
复现源码:
使用python2.7执行,需要提前连接好安卓手机,打开调试模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64from subprocess import Popen, PIPE
import threading
from threading import Thread
import time
pid = 19622 # change to your pid in mobile
def run_logcat():
"""start logcat ,readline from logcat and print"""
print "start logcat thread , %s" % threading.currentThread().getName()
logcat = "adb logcat -v time "
cat_open = Popen(logcat, stdout=PIPE, stderr=PIPE, universal_newlines=True)
index = 0
while index < 20:
print threading.currentThread().getName()
print cat_open.stdout.readline()
time.sleep(1)
index += 1
print "index %s" % index
cat_open.terminate()
# cat_open.kill()
def run_sys():
print "start sys thread , %s" % threading.currentThread().getName()
index = 0
while True:
syst = "adb shell cat /proc/stat"
sys_open = Popen(syst, stdout=PIPE, stderr=PIPE, universal_newlines=True)
print threading.currentThread().getName() + str(index)
print sys_open.communicate()
print "sys open return code %d" % sys_open.returncode
time.sleep(1)
index += 1
if index > 20:
break
def run_proc():
print "start proc thread, %s" % threading.currentThread().getName()
index = 0
while True:
proc = "adb shell cat /proc/%s/stat" % pid
proc_open = Popen(proc, stdout=PIPE, stderr=PIPE, universal_newlines=True)
print threading.currentThread().getName() + str(index)
print proc_open.communicate()
print "proc open return code %s " % proc_open.returncode
time.sleep(1)
index += 1
if index > 20:
break
def run():
logcat_t = Thread(target=run_logcat, name="locat_thread")
proc_t = Thread(target=run_proc, name="proc_thread")
sys_t = Thread(target=run_sys, name="sys_thread")
logcat_t.start()
# time.sleep(1) # if start logcat first and slepp 1s, proc thread ad sys thread will not blck
# proc thread,and sys trhead is block
proc_t.start()
sys_t.start()
if __name__ == "__main__":
run()
在网上找了一张adb 发送、传输指令的时序图,猜测可能是跟adb server有关。在多线程同时向adb server发送指令时,可能会导致后续指令阻塞。如果在python单线程顺序发送指令,或者多线程有sleep的情况下,则不会阻塞。
但是,阻塞在哪一步;阻塞情况怎样才会出现,却不是很清楚。
请问是哪个步骤导致阻塞?