Python開發之路(九)

2021-08-21 04:06:58 字數 4244 閱讀 7144

一、併發程式設計之——程序

什麼是併發程式設計?就是乙個程式可以在同一時刻做多件事情,也就是解決程式中的io操作影響程式效率的問題。

1.程序

什麼是程序?即執行中的程式。且是計算機中最小的資源分配單位。

在python中,每乙個執行中的程式,都是乙個程序,乙個程序就能做一件事,如果有多個程序,就可以做多件事。那麼如何在python中開啟乙個程序呢?

import os

import time

from multiprocessing import process

def

func(num):

print(num,os.getpid())

time.sleep(10)

if __name__ == '__main__':

print(os.getpid())

p = process(target=func,

args=(10

,)) #

創造了乙個程序

p.start() #

開啟程序

print(os.getpid())

這裡引入幾個概念:

子程序:即p

主程序:即執行的這個程式

父程序:即創造子程序的程序

同步和非同步:

所謂同步就像是做飯和洗衣服不能同時做,而非同步像是不衣服放進洗衣機,一邊洗衣服一邊做飯。所以,程序和程序之間是一步的。非同步可以有效地提高程式的效率。

2.守護程序

什麼是守護程序?守護程序也是乙個子程序,當主程序的**執行完畢之後自動結束的子程序叫做守護程序。

import time

def

deamon_func():

while true:

print('

我還活著

') time.sleep(0.5)

def

wahaha():

for i in

range(10):

time.sleep(1)

print(i*'#')

if __name__ == '__main__':

p2 = process(target=wahaha)

p2.start()

p = process(target=deamon_func)

p.daemon = true

p.start()

for i in

range(3):

print(i*'*')

time.sleep(1)

p2.join()

**如上圖,deamon_func就是乙個守護程序,當wahaha執行完畢,即主程序**執行完畢之後自動結束的子程序為守護程序。

3.鎖什麼是鎖?為什麼要引入鎖的概念?

上面我們解決了可以讓多個任務併發進行的問題,但同時也迎來了新的問題,在併發執行程式的同時,他們之間是沒有順序的,也不受我們控制,所以很容易引發資料安全和順序錯亂的問題,下面是乙個搶票例項,如果多程序同時進行的話,得拿到票的人數極有可能會大於票總數。所以這時我們引入了鎖,多個程序在併發執行乙個程式時,就像多個人要進屋子拿東西,第乙個人進去後,會將門鎖上,這時其他人就無法進入屋子,第乙個人拿完東西(**執行完畢)後,開啟門,把鑰匙掛在門上,第二個人再拿鑰匙進去,把門鎖上......以此類推。下面**的執行結果就是只有5個人搶到票。這樣加入鎖後,降低了執行效率,但大大提高了資料安全性。

#

檔案db

的內容為:

#注意一定要用雙引號,不然

json

無法識別

from multiprocessing import process,lock

import time,json,random

def

search():

dic=json.load(open('db'))

print('

\033

[43m

剩餘票數

%s\033

[0m' %dic['count'])

def

get():

dic=json.load(open('db'))

time.sleep(random.random()) #

模擬讀資料的網路延遲

if dic['count'] >0:

dic['count']-=1

time.sleep(random.random()) #

模擬寫資料的網路延遲

json.dump(dic,

open('db'

,'w'))

print('

\033

[32m

購票成功

\033

[0m')

else:

print('

\033

[31m

購票失敗

\033

[0m')

def

task(lock):

search()

lock.acquire()

get()

lock.release()

if __name__ == '__main__':

lock = lock()

for i in

range(100): #

模擬併發

100個客戶端搶票

p=process(target=task,

args=(lock,))

p.start()

4.訊號量

什麼是訊號量?

上面所說的鎖,是在同一時間內,只有乙個執行緒進行對資料進行修改。而semaphore訊號量是同時允許一定數量的執行緒更改資料。假設共有4個ktv小屋,13個使用者想進去唱歌,由於我們說過開啟程序、執行緒都是有時間開銷的,所以在開放小屋時,四個使用者進入小屋,後面的使用者只能在等有人出來了才能進去。**如下:

from multiprocessing import process,semaphore

import time,random

def

go_ktv(sem,user):

sem.acquire()

print('%s

佔到一間

ktv小屋

' %user)

time.sleep(random.randint(0

,3)) #

模擬每個人在

ktv中待的時間不同

sem.release()

if __name__ == '__main__':

sem=semaphore(4)

p_l=

for i in

range(13):

p=process(target=go_ktv,

args=(sem,

'user%s' %i,))

p.start()

for i in p_l:

i.join()

print('**********==

》')

5.事件

python執行緒的事件用於主線程控制其他執行緒的執行,事件主要提供了三個方法 set、wait、clear。

事件處理的機制:全域性定義了乙個「flag」,如果「flag」值為 false,那麼當程式執行 event.wait 方法時就會阻塞,如果「flag」值為true,那麼event.wait 方法時便不再阻塞。

clear:將「flag」設定為false;

set:將「flag」設定為true。

事件主要作用場景:紅綠燈

6.程序池

為什麼要有程序池?程序池的概念。

在程式實際處理問題過程中,忙時會有成千上萬的任務需要被執行,閒時可能只有零星任務。那麼在成千上萬個任務需要被執行的時候,我們就需要去建立成千上萬個程序麼?首先,建立程序需要消耗時間,銷毀程序也需要消耗時間。第二即便開啟了成千上萬的程序,作業系統也不能讓他們同時執行,這樣反而會影響程式的效率。因此我們不能無限制的根據任務開啟或者結束程序。那麼我們要怎麼做呢?

在這裡,要給大家介紹乙個程序池的概念,定義乙個池子,在裡面放上固定數量的程序,有需求來了,就拿乙個池中的程序來處理任務,等到處理完畢,程序並不關閉,而是將程序再放回程序池中繼續等待任務。如果有很多任務需要執行,池中的程序數量不夠,任務就要等待之前的程序執行任務完畢歸來,拿到空閒程序才能繼續執行。也就是說,池中程序的數量是固定的,那麼同一時間最多有固定數量的程序在執行。這樣不會增加作業系統的排程難度,還節省了開閉程序的時間,也一定程度上能夠實現併發效果。

Python開發之路

閱讀目錄 第一篇 python入門 第二篇 資料型別 字元編碼 檔案處理 第三篇 函式 第四篇 模組與包 第五篇 常用模組 第六篇 物件導向 第七篇 物件導向高階 第八篇 異常處理 第九篇 網路程式設計 第十篇 併發程式設計 第十一篇 mysql系列 更新中.閱讀目錄 第一篇 python入門 第二...

Python開發之路

閱讀目錄 詳細內容見老男孩 第一篇 python入門 第二篇 資料型別 字元編碼 檔案處理 第三篇 函式 第四篇 模組與包 第五篇 常用模組 第六篇 物件導向 第七篇 物件導向高階 第八篇 異常處理 第九篇 網路程式設計 第十篇 併發程式設計 第十一篇 mysql系列 更新中 源自 python開發...

Python開發之路

資料型別 字元編碼 檔案處理 內建函式 迭代器,生成器,裝飾器 模組與包 常用模組 正規表示式 物件導向高階 異常處理 網路程式設計 協程io模型 pymysql模組 索引原理 cssdom bomjquery ajax bootstrap bootstrap布局 bootstrap元件 boots...