1. 程式人生 > >程序與執行緒(沒整理好)

程序與執行緒(沒整理好)

基礎知識

  • 併發(一人一段時間做多事)(充分利用資源,提高CPU的利用率)
    • 在作業系統中,併發是指一個時間段中有幾個程式都處於已啟動執行到執行完畢之間,且這幾個程式都是在同一個處理機上執行,但任一個時刻點上只有一個程式在處理機上執行。
  • 並行(多人同時做多事)
    • 當系統有一個以上CPU時,則程式的操作有可能非併發。當一個CPU執行一個程式時,另一個CPU可以執行另一個程式,兩個程式互不搶佔CPU資源,可以同時進行,這種方式我們稱之為並行。如下圖:
      在這裡插入圖片描述
  • 計算機程式只是儲存在磁碟上的可執行二進位制(或其他型別)檔案。只有把它們載入到記憶體中並被作業系統呼叫,才擁有其生命週期。程序則是一個執行中的程式。
  • 每個程序都擁有自己的地址空間,記憶體,資料棧以及其他用於跟蹤執行的輔助資料。
  • 作業系統直接管理程序,作業系統管理其上所有程序的執行,併為這些程序合理分配時間。
    案例:
    #模仿耗時函式
    import time
    #import random
    def func():
    #模仿耗時
    time.sleep(3)
    if name==“main”:
    s_time = time.time()#獲取開始時間
    func()
    func()
    e_time = time.time()#獲取結束時間
    print(“耗時%s秒”%(e_time-s_time))

多程序

#多程序提高執行效率
import time
from multiprocessing import Process
def func():
#模仿耗時三秒
print(1)
time.sleep(3)
if name

==“main”:
s_time = time.time()
#建立一個程序func是要執行的函式
p1 = Process(target=func)
#啟動這個程序
p1.start()
func()
e_time = time.time()
print(e_time-s_time) #1,1,3.005776882171631
多程序使用流程
在這裡插入圖片描述
多程序
from multiprocessing import Process
import time
def func1(a,b):
time.sleep(2)
print(res)
res = a + b

if name==“main”:
s_time = time.time()
func1(1+1)
p1 = Process(target=func1,args=(2,2))
#p1 = Process(func1,args=(2,2))
p1.start() #啟動程序
e_time = time.time #2,2.00451…,4
- 程序數量不多於 CPU核心數量!
- 現在執行的程式都是輪詢排程產生的並行假象。
- 但是在Python程式,使用者層面的確獲得了並行!

多執行緒

- 執行緒,有時被稱為輕量程序(Lightweight Process,LWP),是程式執行流的最小單元。 多工可以由多程序完成,也可以有一個程序內的多執行緒完成。我們前面講過程序是由若干執行緒組成的,一個程序至少有一個執行緒。
- 當其他執行緒執行時,它可以被搶佔(中斷)和臨時掛起(也成為睡眠) — 讓步。
- 執行緒的輪詢排程機制類似於程序的輪詢排程。只不過這個排程不是由作業系統來負責,而是由Python直譯器來負責。
案例:

#多執行緒執行耗時任務
import time
from threading import Thread
def func():
print(“任務開始了”)
time.sleep(2)
if name==“main”:
s_time = time.time()
t1 = Thread(target=func)
t1.start()
func()
e_time = time.time()
print(e_time-s_time) #2.00286…
多執行緒使用流程
在這裡插入圖片描述
- python中多執行緒只能併發,不能並行

Gil鎖

- Python在設計的時候,還沒有多核處理器的概念,因此,為了設計方便與執行緒安全,直接設計了一個鎖。這個鎖要求,任何程序中,一次只能有一個執行緒在執行.因此,並不能為多個執行緒分配多個CPU。所以Python中的執行緒只能實現併發,而不能實現真正的並行。但是Python3中的GIL鎖有一個很棒的設計,在遇到任何IO阻塞(不是耗時)的時候,會自動切換執行緒。

在這裡插入圖片描述

用多程序,多執行緒寫併發伺服器

併發伺服器(多程序)

#也適合在Windows下執行
import multiprocessing
import socket
import os
os.getpid() #當前程序id
def task(sock):#子程序中的任務邏輯
print(“我是程序%s”%os.getpid())
while True:
recv_data = sock.recv(1024)
if recv_data:
print(recv_data.decode(“utf-8”))
sock.send(recv_data)
else:
break
sock.close()
if name==“main”":
server = socket.socket()
server.bind(("",6969))
server.listen(20)
while True:
conn,addr = server.accept()
#每當有一個連線進來之後,就生成一個新的程序去處理
process = multiprocessing.Process(
target=task,
args=(conn,)
)
process.start()

併發伺服器(多執行緒)

from threading import Thread
import socket
import os #當前程序id
os.getpid()
def task(sock): #子執行緒中的任務邏輯
print(“我是執行緒%s”%os.getpid())
while True:
recv_data = sock.recv(1024)
if recv_data:
print(recv_data.decode(“utf-8”))
sock.send(recv_data)
else:
break
sock.close()
if name==“main”:
server = socket.socket()
server.bind(("",8686))
server.listen(20)
while True:
conn,addr = server.accept()
#每當有一個連線進來之後,就生成一個新的執行緒去處理
thread = Thread(
target=task,
args=(conn,)
)
thread.start()