### 主要包含两部分:多线程 及 外部程序调用
所有的说明和注释都包含在代码注释中。
### 主要包含两部分:多线程 及 外部程序调用
## 多线程创建
# 1.使用threading模块,调用threading.Thread()生成Thread对象
# 2.在程序的所有线程终止之前,python程序不会终止。即使最初的线程已经终止,其他生成的线程依然要执行结束。
import threading,time
print('Start of program.')
def takeNewApp():
time.sleep(5)
print('Wake Up.')
threadObj = threading.Thread(target=takeNewApp)
threadObj.start()
print('End of program.')
## 向线程的目标函数传参
# 以 print('cats','dogs','frogs',sep='&')为例,有三个常规参数,一个关键字参数
# 如果要向新线程中的print函数传递参数,就使用threading.Thread()函数的args和kwargs关键字参数
# 常规参数可以作为一个列表或元组,传递给threading.Thread()的args关键字参数
# 关键字参数可作为一个字典,传递给threading.Thread()的kwargs关键字参数
print('cats','dogs','frogs',sep=' & ') # cats & dogs & frogs
import threading
threadObj = threading.Thread(target=print,args=['cats','dogs','frogs'],kwargs={'sep':' & '})
threadObj.start() # cats & dogs & frogs
# 注意:为避免并发问题,绝不让多个线程读取或写入相同的变量。当创建一个新的Thread对象时,要确保其目标函数只
# 使用该函数中的局部变量,这将避免程序中难以调试的并发问题。
## 多线程的漫画站下载程序 另外base_webops.py中为单线程版本
# Downloads XKCD comics using multiple threads.
import requests, os, bs4, threading
os.makedirs('xkcd',exist_ok=True) # store comics in ./xkcd
def downloadXkcd(startComic,endComic):
for urlNumber in range(startComic,endComic):
# Download the page.
print('Downloading page http://xkcd.com/%s...' % (urlNumber))
res = requests.get('http://xkcd.com/%s' % (urlNumber))
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text)
# Find the URL of the comic image
comicElem = soup.select('#comic img')
if comicElem == []:
print('Could not find comic image.')
else:
comicUrl = 'http:' + comicElem[0].get('src')
# Download the image.
print('Donwloading image %s...' % (comicUrl))
res = requests.get(comicUrl)
res.raise_for_status()
# Save the image to ./xkcd
imageFile = open(os.path.join('xkcd',os.path.basename(comicUrl)),'wb')
for chunk in res.iter_content(100000):
imageFile.write(chunk)
imageFile.close()
# Create and start the Thread objects.
downloadThreads = [] # a list of all the Thread objects
for i in range(0,1400,100):
downThread = threading.Thread(target=downloadXkcd,args=(i,i+99))
downloadThreads.append(downThread)
downThread.start()
# Wait for all threads to end.
for downThread in downloadThreads:
downThread.join() # 调用Thread对象join()方法阻塞,直到该线程完成
print('Done.')
### 外部调用
## 调用其他程序 subprocess
# 返回的Popen对象有两个方法:poll()和wait()
# poll() 询问调用是否执行完毕。 正在执行 返回 None,已正常完成 返回 0,错误导致终止 返回非零退出代码,通常为1
# wait() 等待调用进程执行完毕。 返回值时调用进程的整数退出代码。
import subprocess
calcProc = subprocess.Popen('c:\\windows\\system32\\calc.exe')
calcProc.poll() == None # 计算器打开之前 True
calcProc.wait() # 0
calcProc.poll() == None # 计算器打开之后 False
calcProc.poll() # 0
# 调用其他进程时传递参数
subprocess.Popen(['c:\\windows\\notepad.exe','c:\\temp\\1.txt'])
subprocess.Popen(['C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python36\\python.exe','c:\\temp\\test.py'])
## 例子:倒数10秒,打开文件
# A simple countdown script.
import time ,subprocess
timeLeft = 10
while timeLeft > 0:
print(timeLeft,end='') # 不换行
time.sleep(1)
timeLeft -= 1
# At the end of the countdown,open a File.
subprocess.Popen(['c:\\windows\\notepad.exe','c:\\temp\\1.txt'])