進(jìn)程與線程的簡(jiǎn)介:
進(jìn)程 - 操作系統(tǒng)分配內(nèi)存的基本單位,進(jìn)程之間的內(nèi)存相互獨(dú)立的,ipc機(jī)制可以相互訪問,套接字(sokect)
線程 - 一個(gè)進(jìn)程可以劃分為多個(gè)線程,線程是進(jìn)程的執(zhí)行單元也是操作系統(tǒng)分配cpu的基本單元
為什么要使用多線程:得到更多的cpu的調(diào)用
1 如果一個(gè)任務(wù)執(zhí)行時(shí)間很長(zhǎng) 我們就可以將一個(gè)任務(wù)分為多個(gè)線程 改善程序的執(zhí)行效率 縮短執(zhí)行時(shí)間
2 改善用戶體驗(yàn)
進(jìn)程的定義與使用
關(guān)鍵字Process例如:
import time
from multiprocessing import Process
import os
# process
# thread
def output():
print(os.getpid()) # 端口號(hào)
while True:
print('ljl', end='', flush=True)
time.sleep(1)
def main():
print(os.getpid())
Process(target=output).start() # 子進(jìn)程
while True:
print('zy', end='', flush=True)
time.sleep(1)
if __name__ == '__main__':
main()
使用進(jìn)程模擬下載文件:
import time
import random
from threading import Thread
from multiprocessing import Process
# 如果多個(gè)任務(wù)之間沒有任何的關(guān)聯(lián)(獨(dú)立子任務(wù))而希望利用CPU的多核特性
# 那么我們推薦使用多進(jìn)程
# Information Technology
# 摩爾定律 -
# 安迪比爾定律 -
# 反摩爾定律 -
def download(filename):
print('開始下載%s。。。' % filename)
delay = random.randint(5, 15)
time.sleep(delay)
print('%s下載完成,用時(shí)%d秒.' % (filename, delay))
def main():
start = time.time()
p1 = Process(target=download, args=('python從入門到住院.pdf', ))
p1.start()
p2 = Process(target=download, args=('pekin hot.avi.pdf',))
p2.start()
p1.join() # 等待p1進(jìn)程結(jié)束 join()保護(hù)進(jìn)程
p2.join()
end = time.time()
print('總共耗費(fèi)了%f秒' % (end - start))
if __name__ == '__main__':
main()
線程
守護(hù)線程 不值得保留的線程 其它線程如果都執(zhí)行完畢了那么守護(hù)線程自動(dòng)結(jié)束
daemon=True 將線程設(shè)置為守護(hù)線程
t1 = Thread(target=output, args=('zy', ), daemon=True) # 定義一個(gè)名為t1的線程, target 表示的是要執(zhí)行的動(dòng)作 方法 函數(shù)名
t1.start()
t2 = Thread(target=output, args=('ljl', ), daemon=True) # deamon 守護(hù)線程 當(dāng)主程序結(jié)束則結(jié)束
t2.start()
使用線程
當(dāng)然創(chuàng)建線程我們也可以使用函數(shù)來創(chuàng)建,例如:
from threading import Thread
# 創(chuàng)建線程的兩種方式
# 1. 直接創(chuàng)建Thread對(duì)象并通過target參數(shù)指定線程啟動(dòng)后要執(zhí)行的任務(wù)
# 2. 繼承Thread自定義線程 通過寫run方法指定線程啟動(dòng)后執(zhí)行的任務(wù)
class PrintThread(Thread):
def __init__(self, string, count):
super().__init__()
self._string = string
self._count = count
def run(self): # 這里的run方法不能更改函數(shù)名
"""需要寫的判斷條件或者循環(huán)條件"""
for _ in range(self._count):
print(self._string, end='', flush=True) # flush是將相應(yīng)的立即輸出
def main():
PrintThread('pin', 5).start()
PrintThread('pon', 5).start()
if __name__ == '__main__':
main()
1.多線程控制小車的移動(dòng)以及繪制窗口。
from random import randint
from threading import Thread
import pygame
import time
# 2 賽車游戲 5 個(gè)線程控制5個(gè)車移動(dòng)
BLACK_COLOR = [0, 0, 0]
GREEN_COLOR = [0, 255, 0]
WHITE_COLOR = [255, 255, 255]
class GameObject(object):
def __init__(self, x, y, size):
self._x = x
self._y = y
self._size = size
@property
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = x
def draw(self, screen):
pass
class Car(GameObject):
def __init__(self, x, y, size):
super().__init__(x, y, size)
def draw(self, screen):
pygame.draw.rect(screen, GREEN_COLOR, [self._x, self._y, self._size, self._size], 0)
pygame.draw.rect(screen, WHITE_COLOR, [self._x, self._y, self._size, self._size], 1)
def move(self):
if self._x + self._size < 400:
self._x += randint(5, 10)
def main():
class My_thread(Thread):
def run(self):
while True:
screen.fill((255, 255, 255))
pygame.draw.line(screen, BLACK_COLOR, (30, 0), (30, 200), 4)
pygame.draw.line(screen, BLACK_COLOR, (400, 0), (400, 200), 4)
for car in car_list:
car.draw(screen)
pygame.display.flip()
time.sleep(0.1)
for car in car_list:
car.move()
car_list = []
for index in range(5):
car1 = Car(10, 10 + 40 * index, 20)
car_list.append(car1)
pygame.init()
screen = pygame.display.set_mode([500, 200])
pygame.display.set_caption('小車車')
my_thread = My_thread(daemon=True)
my_thread.start()
runing = True
while runing:
for event in pygame.event.get():
if event.type == pygame.QUIT:
runing = False
# screen.fill([200, 200, 200])
pygame.display.flip()
pygame.quit()
if __name__ == '__main__':
main()
2.多個(gè)人給一個(gè)銀行賬戶轉(zhuǎn)錢
import time
from threading import Thread, Lock
class Account(object):
def __init__(self):
self._balance = 0
self._lock = Lock()
@property
def balance(self):
return self._balance
def deposit(self, money):
# 當(dāng)多個(gè)線程同時(shí)訪問一個(gè)資源的時(shí)候 就有可能因?yàn)楦?jìng)爭(zhēng)資源導(dǎo)致資源的狀態(tài)錯(cuò)誤
# 被多個(gè)線程訪問的資源我們通常稱之為臨界資源 對(duì)臨界資源的訪問需要加上保護(hù)
if money > 0:
# 加鎖 別亂加鎖
self._lock.acquire()
try:
new_balance = self._balance + money
time.sleep(0.01)
self._balance = new_balance
finally:
# 解鎖
self._lock.release()
class AddMoneyThread(Thread):
def __init__(self, user):
super().__init__()
self._user = user
def run(self):
self._user.deposit(1)
def main():
account = Account()
tlist = [] # 等下保存所要執(zhí)行的線程
# 創(chuàng)建多個(gè)線程可以使用循環(huán)來解決
for _ in range(100):
t = AddMoneyThread(account)
tlist.append(t)
t.start()
for t in tlist:
# 等所有線程結(jié)束后才結(jié)束該主線程
t.join()
print('賬戶余額: %d' % account.balance)
if __name__ == '__main__':
main()