python进阶宝典16- 多线程与外部调用

### 主要包含两部分:多线程 及 外部程序调用

所有的说明和注释都包含在代码注释中。

### 主要包含两部分:多线程 及 外部程序调用

##  多线程创建
# 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'])

你可能感兴趣的:(python)