同步和異步
同步和異步是相對于操作結(jié)果來說,會不會等待結(jié)果
阻塞和非阻塞
阻塞是在煮稀飯的過程中砰蠢,你不能去干其他的事情婆咸。非阻塞是在煮稀飯的過程中,你還可以去做其他的事情筷屡。阻塞和非阻塞是相對于線程是否被阻塞
并發(fā)和并行
如果某個系統(tǒng)支持兩個或者多個動作(Action)同時存在涧偷,那么這個系統(tǒng)就是一個并發(fā)系統(tǒng)。如果某個系統(tǒng)支持兩個或者多個動作同時執(zhí)行毙死,那么這個系統(tǒng)就是一個并行系統(tǒng)燎潮。并發(fā)系統(tǒng)與并行系統(tǒng)這兩個定義之間的關(guān)鍵差異在于“存在”這個詞。
并行”概念是“并發(fā)”概念的一個子集扼倘。也就是說确封,你可以編寫一個擁有多個線程或者進(jìn)程的并發(fā)程序,但如果沒有多核處理器來執(zhí)行這個程序,那么就不能以并行方式來運(yùn)行代碼爪喘。因此颜曾,凡是在求解單個問題時涉及多個執(zhí)行流程的編程模式或者執(zhí)行行為,都屬于并發(fā)編程的范疇秉剑。
并發(fā)
并行
進(jìn)程
進(jìn)程即正在執(zhí)行的一個過程泛豪。進(jìn)程是對正在運(yùn)行程序的一個抽象。操作系統(tǒng)以進(jìn)程為單位分配存儲空間侦鹏,每個進(jìn)程都有自己的地址空間候址、數(shù)據(jù)棧以及其他用于跟蹤進(jìn)程執(zhí)行的輔助數(shù)據(jù),操作系統(tǒng)管理所有進(jìn)程的執(zhí)行种柑,為它們合理的分配資源。進(jìn)程可以通過fork或spawn的方式來創(chuàng)建新的進(jìn)程來執(zhí)行其他的任務(wù)匹耕,不過新的進(jìn)程也有自己獨(dú)立的內(nèi)存空間,因此必須通過進(jìn)程間通信機(jī)制(IPC,Inter-Process Communication)來實(shí)現(xiàn)數(shù)據(jù)共享湃望,具體的方式包括管道耕驰、信號、套接字既鞠、共享內(nèi)存區(qū)等煤傍。
multiprocessing模塊提供了一個Process類來代表一個進(jìn)程對象
多個進(jìn)程可以同時進(jìn)行,使用join阻塞進(jìn)程
import os
import time
from random import randint
from multiprocessing import Process
def coding():
print('開始擼代碼,PID是%s' % os.getpid())
time.sleep(randint(1, 3))
print('寫累了嘱蛋,不擼了蚯姆,PID是%s' % os.getpid())
def play_weixin():
print('玩一會微信,PID是%s' % os.getpid())
time.sleep(randint(1, 2))
print('不玩微信了洒敏,開始擼代碼龄恋,PID是%s' % os.getpid())
if __name__ == '__main__':
# 創(chuàng)建進(jìn)程
p1 = Process(target=coding)
p2 = Process(target=coding)
p3 = Process(target=play_weixin)
# 啟動進(jìn)程
p1.start()
# 阻塞進(jìn)程p1
# p1.join()
# 啟動進(jìn)程
p2.start()
p3.start()
# 主進(jìn)程
while True:
time.sleep(3)
print('我是主進(jìn)程,PID是%s' % os.getpid())
線程
一個進(jìn)程中的多個線程可以共享一個資源內(nèi)存空間
Python的標(biāo)準(zhǔn)庫提供了兩個模塊:thread和threading凶伙,thread是低級模塊郭毕,threading是高級模塊,對thread進(jìn)行了封裝函荣。絕大多數(shù)情況下显押,我們只需要使用threading這個高級模塊。
啟動一個線程,創(chuàng)建threading的實(shí)例傻挂,然后直接start()就可以啟動我們定義的線程了乘碑。
start和run的區(qū)別
start() 方法是啟動一個子線程,線程名就是我們定義的name踊谋,或者默認(rèn)的線程名Thread-1蝉仇,
Thread-2......
run() 方法并不啟動一個新線程,就是在主線程中調(diào)用了一個普通函數(shù)而已。
# !/usr/bin/env/python
# .*. encoding:utf-8 -*-
import threading
import time
class DataCopy(threading.Thread):
def __init__(self, dbname):
super(DataCopy, self).__init__()
self.dbName = dbname
def run(self):
print('Thread %s is running' % threading.current_thread().name)
print('開始備份數(shù)據(jù)庫:%s' % self.dbName)
time.sleep(5)
print('數(shù)據(jù)庫%s備份結(jié)束' % self.dbName)
print('Thread %s is ended' % threading.current_thread().name)
thread1 = DataCopy('database1')
# 守護(hù)線程,只要主線程結(jié)束,子線程就結(jié)束
thread1.daemon = True
thread1.start()
# 線程阻塞
# thread1.join()
print('End')