最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python并發(fā)之多進(jìn)程的方法實(shí)例代碼

 更新時(shí)間:2018年08月15日 14:51:46   作者:碼、、碼  
這篇文章主要介紹了Python并發(fā)之多進(jìn)程的方法實(shí)例代碼,文中也提到了進(jìn)程與線程的共同點(diǎn),需要的朋友跟隨腳本之家小編一起看看吧

一,進(jìn)程的理論基礎(chǔ)

一個(gè)應(yīng)用程序,歸根結(jié)底是一堆代碼,是靜態(tài)的,而進(jìn)程才是執(zhí)行中的程序,在一個(gè)程序運(yùn)行的時(shí)候會(huì)有多個(gè)進(jìn)程并發(fā)執(zhí)行。

進(jìn)程和線程的區(qū)別:

  • 進(jìn)程是系統(tǒng)資源分配的基本單位。
  • 一個(gè)進(jìn)程內(nèi)可以包含多個(gè)線程,屬于一對(duì)多的關(guān)系,進(jìn)程內(nèi)的資源,被其內(nèi)的線程共享
  • 線程是進(jìn)程運(yùn)行的最小單位,如果說(shuō)進(jìn)程是完成一個(gè)功能,那么其線程就是完成這個(gè)功能的基本單位
  • 進(jìn)程間資源不共享,多進(jìn)程切換資源開銷,難度大,同一進(jìn)程內(nèi)的線程資源共享,多線程切換資源開銷,難度小

進(jìn)程與線程的共同點(diǎn):

都是為了提高程序運(yùn)行效率,都有執(zhí)行的優(yōu)先權(quán)

二,Python的多進(jìn)程( multiprocessing模塊)

創(chuàng)建一個(gè)進(jìn)程(和創(chuàng)建線程類似)

方法一:創(chuàng)建Process對(duì)象,通過(guò)對(duì)象調(diào)用start()方法啟動(dòng)進(jìn)程

from multiprocessing import Process
def foo(name):
 print('hello,%s'%name)
if __name__ == '__main__':
 p1=Process(target=foo,args=('world',))
 p2 = Process(target=foo, args=('China',))
 p1.start()
 p2.start()
 print('=====主進(jìn)程=====')
 # == == =主進(jìn)程 == == =
 # hello, world
 # hello, China
 #主進(jìn)程和子進(jìn)程并發(fā)執(zhí)行 

注意:Process對(duì)象只能在在 if __name__ == '__main__':下創(chuàng)建,不然會(huì)報(bào)錯(cuò)。

方法二:自定義一個(gè)類繼承Process類,并重寫run()方法,將執(zhí)行代碼放在其內(nèi)

from multiprocessing import Process
class MyProcess(Process):
 def __init__(self,name):
  super().__init__()
  self.name = name
 def run(self):
  print('hello,%s'%self.name)
if __name__ == '__main__':
 myprocess1 = MyProcess('world')
 myprocess2 = MyProcess('world')
 myprocess1.start()
 myprocess2.start()

Process內(nèi)置方法

實(shí)例方法:

p.start():?jiǎn)?dòng)進(jìn)程,并調(diào)用該子進(jìn)程中的p.run()

p.run():進(jìn)程啟動(dòng)時(shí)運(yùn)行的方法,正是它去調(diào)用target指定的函數(shù),我們自定義類的類中一定要實(shí)現(xiàn)該方法 

p.terminate():強(qiáng)制終止進(jìn)程p,不會(huì)進(jìn)行任何清理操作,如果p創(chuàng)建了子進(jìn)程,該子進(jìn)程就成了僵尸進(jìn)程,使用該方法需要特別小心這種情況。如果p還保存了一個(gè)鎖那么也將不會(huì)被釋放,進(jìn)而導(dǎo)致死鎖

p.is_alive():如果p仍然運(yùn)行,返回True

p.join([timeout]):主線程等待p終止。timeout是可選的超時(shí)時(shí)間
Process屬性

p.daemon:默認(rèn)值為False,如果設(shè)為True,代表p為后臺(tái)運(yùn)行的守護(hù)進(jìn)程,當(dāng)p的父進(jìn)程終止時(shí),p也隨之終止,并且設(shè)定為True后,p不能創(chuàng)建自己的新進(jìn)程,必須在p.start()之前設(shè)置

p.name:進(jìn)程的名稱

p.pid:進(jìn)程的pid

p.exitcode:進(jìn)程在運(yùn)行時(shí)為None、如果為–N,表示被信號(hào)N結(jié)束(了解即可)

守護(hù)進(jìn)程

類似于守護(hù)線程,只不過(guò)守護(hù)線程是對(duì)象的一個(gè)方法,而守護(hù)進(jìn)程封裝成對(duì)象的屬性。

from multiprocessing import Process
import time
class MyProcess(Process):
 def __init__(self,name):
  super().__init__()
  self.name = name
 def run(self):
  time.sleep(3)
  print('hello,%s'%self.name)
if __name__ == '__main__':
 myprocess1=MyProcess('world')
 myprocess1.daemon = True
 myprocess1.start()
 print('結(jié)束')
#不會(huì)輸出‘hello world',因?yàn)樵O(shè)置為守護(hù)進(jìn)程,主進(jìn)程不會(huì)等待

也可以使用join方法,使主進(jìn)程等待

from multiprocessing import Process
import time
class MyProcess(Process):
 def __init__(self,name):
  super().__init__()
  self.name = name
 def run(self):
  time.sleep(3)
  print('hello,%s'%self.name)
if __name__ == '__main__':
 myprocess1=MyProcess('world')
 myprocess1.daemon = True
 myprocess1.start()
 myprocess1.join() #程序阻塞
 print('結(jié)束')
join()

進(jìn)程同步和鎖

進(jìn)程雖然不像線程共享資源,但是這并不意味著進(jìn)程間不 需要加鎖,比如不同進(jìn)程會(huì)共享同一個(gè)終端 ( 屏幕),或者操作同一個(gè)文件,數(shù)據(jù)庫(kù),那么數(shù)據(jù)安全還是很有必要的,因此我們可以加鎖,

from multiprocessing import Process,Lock
import time
def a_print(l): #需要傳入對(duì)象,因?yàn)樾畔⒉还蚕?
 l.acquire()
 print('我要打印信息')
 time.sleep(1)
 print('我打印完了')
 l.release()
if __name__ == '__main__':
 l = Lock()
 for i in range(20):
  p = Process(target=a_print,args=(l,))
  p.start()

信號(hào)量(Semaphore)

能夠并發(fā)執(zhí)行的進(jìn)程數(shù),超出的進(jìn)程阻塞,直到有進(jìn)程運(yùn)行完成。

Semaphore管理一個(gè)內(nèi)置的計(jì)數(shù)器,

每當(dāng)調(diào)用acquire()時(shí)內(nèi)置計(jì)數(shù)器-1;

調(diào)用release() 時(shí)內(nèi)置計(jì)數(shù)器+1;

計(jì)數(shù)器不能小于0;當(dāng)計(jì)數(shù)器為0時(shí),acquire()將阻塞進(jìn)程直到其他進(jìn)程調(diào)用release()。

from multiprocessing import Process,Queue,Semaphore
import time,random
def seat(s,n):
 s.acquire()
 print('學(xué)生%d坐下了'%n)
 time.sleep(random.randint(1,2))
 s.release()
if __name__ == '__main__':
 s = Semaphore(5)
 for i in range(20):
  p = Process(target=seat,args=(s,i))
  p.start()
 print('-----主進(jìn)程-------')

注意:其實(shí)信號(hào)量和鎖類似,只是限制進(jìn)程運(yùn)行某個(gè)代碼塊的數(shù)量(鎖為1個(gè)),并不是能限制并發(fā)的進(jìn)程,如上述代碼,一次性還是創(chuàng)建了20個(gè)進(jìn)程

事件(Event)

from multiprocessing import Process,Event
import time, random
def eating(event):
 event.wait()
 print('去吃飯的路上...')
def makeing(event):
 print('做飯中')
 time.sleep(random.randint(1,2))
 print('做好了,快來(lái)...')
 event.set()
if __name__ == '__main__':
 event=Event()
 t1 = Process(target=eating,args=(event,))
 t2 = Process(target=makeing,args=(event,))
 t1.start()
 t2.start()
 # 做飯中
 # 做好了,快來(lái)...
 # 去吃飯的路上...

和線程事件幾乎一致

進(jìn)程隊(duì)列(Queue)

進(jìn)程隊(duì)列是進(jìn)程通訊的方式之一。使用multiprocessing 下的Queue

from multiprocessing import Process,Queue
import time
def func1(queue):
 while True:
  info=queue.get()
  if info == None:
   return 
  print(info)
def func2(queue):
 for i in range(10):
  time.sleep(1)
  queue.put('is %d'%i)
 queue.put(None) #結(jié)束的標(biāo)志
if __name__ == '__main__':
 q = Queue()
 p1 = Process(target=func1,args=(q,))
 p2 = Process(target=func2, args=(q,))
 p1.start()
 p2.start()
Queue類的方法,源碼如下:
class Queue(object):
 def __init__(self, maxsize=-1): #可以傳參設(shè)置隊(duì)列最大容量
  self._maxsize = maxsize
 def qsize(self): #返回當(dāng)前時(shí)刻隊(duì)列中的個(gè)數(shù)
  return 0
 def empty(self): #是否為空
  return False
 def full(self): 是否滿了
  return False
 def put(self, obj, block=True, timeout=None): #放值,blocked和timeout。如果blocked為True(默認(rèn)值),并且timeout為正值,該方法會(huì)阻塞timeout指定的時(shí)間,直到該隊(duì)列有剩余的空間。如果超時(shí),會(huì)拋出Queue.Full異常。如果blocked為False,但該Queue已滿,會(huì)立即拋出Queue.Full異常
  pass
 def put_nowait(self, obj): #=put(False)
  pass
 def get(self, block=True, timeout=None): 獲取值,get方法有兩個(gè)可選參數(shù):blocked和timeout。如果blocked為True(默認(rèn)值),并且timeout為正值,那么在等待時(shí)間內(nèi)沒有取到任何元素,會(huì)拋出Queue.Empty異常。如果blocked為False,有兩種情況存在,如果Queue有一個(gè)值可用,則立即返回該值,否則,如果隊(duì)列為空,則立即拋出Queue.Empty異常.
  pass
 def get_nowait(self): # = get(False)
  pass
 def close(self): #將隊(duì)列關(guān)閉
  pass
 def join_thread(self): #略,幾乎不用
  pass
 def cancel_join_thread(self):
  pass

進(jìn)程隊(duì)列源碼注釋

進(jìn)程池

進(jìn)程的消耗是很大的,因此我們不能無(wú)節(jié)制的開啟新進(jìn)程,因此我們可以 通過(guò)維護(hù)一個(gè)進(jìn)程池來(lái)控制進(jìn)程的數(shù)量 。這就不同于信號(hào)量,進(jìn)程池可以從源頭控制進(jìn)程數(shù)量。在Python中可以通過(guò)如下方法使用

同步調(diào)用

from multiprocessing import Pool
import time, random, os
def func(n):
 pid = os.getpid()
 print('進(jìn)程%s正在處理第%d個(gè)任務(wù)'%(pid,n),'時(shí)間%s'%time.strftime('%H-%M-%S'))
 time.sleep(2)
 res = '處理%s'%random.choice(['成功','失敗'])
 return res
if __name__ == '__main__':
 p = Pool(4) #創(chuàng)建4個(gè)進(jìn)程,
 li = []
 for i in range(10):
  res = p.apply(func,args=(i,)) 交給進(jìn)程池處理,處理完成才返回值,會(huì)阻塞,即使池內(nèi)還有空余進(jìn)程,相當(dāng)于順序執(zhí)行
  li.append(res)
 for i in li:
  print(i)

#進(jìn)程1916正在處理第0個(gè)任務(wù) 時(shí)間21-02-53
#進(jìn)程1240正在處理第1個(gè)任務(wù) 時(shí)間21-02-55
#進(jìn)程3484正在處理第2個(gè)任務(wù) 時(shí)間21-02-57
#進(jìn)程7512正在處理第3個(gè)任務(wù) 時(shí)間21-02-59
#進(jìn)程1916正在處理第4個(gè)任務(wù) 時(shí)間21-03-01
#進(jìn)程1240正在處理第5個(gè)任務(wù) 時(shí)間21-03-03
#進(jìn)程3484正在處理第6個(gè)任務(wù) 時(shí)間21-03-05
#進(jìn)程7512正在處理第7個(gè)任務(wù) 時(shí)間21-03-07
#進(jìn)程1916正在處理第8個(gè)任務(wù) 時(shí)間21-03-09
#進(jìn)程1240正在處理第9個(gè)任務(wù) 時(shí)間21-03-11

從結(jié)果可以發(fā)現(xiàn)兩點(diǎn):

  1. 不是并發(fā)處理
  2. 一直都只有四個(gè)進(jìn)程,串行執(zhí)行

因此進(jìn)程池提供了 異步處理 的方式

from multiprocessing import Pool
import time, random, os
def func(n):
 pid = os.getpid()
 print('進(jìn)程%s正在處理第%d個(gè)任務(wù)'%(pid,n),'時(shí)間%s'%time.strftime('%H-%M-%S'))
 time.sleep(2)
 res = '處理%s'%random.choice(['成功','失敗'])
 return res

if __name__ == '__main__':
 p = Pool(4)
 li = []
 for i in range(10):
  res = p.apply_async(func,args=(i,)) 結(jié)果不會(huì)立刻返回,遇到阻塞,開啟下一個(gè)進(jìn)程,在這,相當(dāng)于幾乎同時(shí)出現(xiàn)四個(gè)打印結(jié)果(一個(gè)線程處理一個(gè)任務(wù),處理完下個(gè)任務(wù)才能進(jìn)來(lái))
  li.append(res)

 p.close() #join之前需要關(guān)閉進(jìn)程池
 p.join() #因?yàn)楫惒?,所以需要等待池?nèi)進(jìn)程工作結(jié)束再繼續(xù)
 for i in li:
  print(i.get()) #i是一個(gè)對(duì)象,通過(guò)get方法獲取返回值,而同步則沒有該方法

關(guān)于回調(diào)函數(shù)

from multiprocessing import Pool
import time, random, os
def func(n):
 pid = os.getpid()
 print('進(jìn)程%s正在處理第%d個(gè)任務(wù)'%(pid,n),'時(shí)間%s'%time.strftime('%H-%M-%S'))
 time.sleep(2)
 res = '處理%s'%random.choice(['成功','失敗'])
 return res

def foo(info):
 print(info) #傳入值為進(jìn)程執(zhí)行結(jié)果

if __name__ == '__main__':
 p = Pool(4)
 li = []
 for i in range(10):
  res = p.apply_async(func,args=(i,),callback = foo) callback()回調(diào)函數(shù)會(huì)在進(jìn)程執(zhí)行完之后調(diào)用(主進(jìn)程調(diào)用) 
  li.append(res)

 p.close() 
 p.join() 
 for i in li:
  print(i.get()) 

有回調(diào)函數(shù)

總結(jié)

以上所述是小編給大家介紹的Python并發(fā)之多進(jìn)程的方法實(shí)例代碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Python pickle模塊用法實(shí)例

    Python pickle模塊用法實(shí)例

    這篇文章主要介紹了Python pickle模塊用法實(shí)例,python的pickle模塊實(shí)現(xiàn)了基本的數(shù)據(jù)序列和反序列化,需要的朋友可以參考下
    2015-04-04
  • python生成lmdb格式的文件實(shí)例

    python生成lmdb格式的文件實(shí)例

    今天小編就為大家分享一篇python生成lmdb格式的文件實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • Python項(xiàng)目管理的利器Poetry的使用

    Python項(xiàng)目管理的利器Poetry的使用

    在?Python?項(xiàng)目開發(fā)中,包管理、依賴管理和虛擬環(huán)境的創(chuàng)建一直是開發(fā)者們經(jīng)常面對(duì)的難題,本文主要介紹了Python項(xiàng)目管理的利器Poetry的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-04-04
  • Python 同級(jí)目錄(兄弟目錄)調(diào)用方式

    Python 同級(jí)目錄(兄弟目錄)調(diào)用方式

    這篇文章主要介紹了Python 同級(jí)目錄(兄弟目錄)調(diào)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 基于python實(shí)現(xiàn)matlab filter函數(shù)過(guò)程詳解

    基于python實(shí)現(xiàn)matlab filter函數(shù)過(guò)程詳解

    這篇文章主要介紹了基于python實(shí)現(xiàn)matlab filter函數(shù)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Python的requests網(wǎng)絡(luò)編程包使用教程

    Python的requests網(wǎng)絡(luò)編程包使用教程

    requests包為Python擴(kuò)展了各種基于HTTP的網(wǎng)絡(luò)數(shù)據(jù)操作功能,包括各種請(qǐng)求與session和cookie等的追加,very強(qiáng)大,下面我們就來(lái)看一下Python的requests網(wǎng)絡(luò)編程包使用教程
    2016-07-07
  • Python獲取圖像中像素點(diǎn)坐標(biāo)實(shí)例代碼

    Python獲取圖像中像素點(diǎn)坐標(biāo)實(shí)例代碼

    當(dāng)我們處理圖像的時(shí)候避免不了要對(duì)訪問(wèn),或是讀取某一個(gè)像素點(diǎn)的值,下面這篇文章主要給大家介紹了關(guān)于利用Python如何獲取圖像中像素點(diǎn)坐標(biāo)的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • python時(shí)間與Unix時(shí)間戳相互轉(zhuǎn)換方法詳解

    python時(shí)間與Unix時(shí)間戳相互轉(zhuǎn)換方法詳解

    這篇文章主要介紹了python時(shí)間與Unix時(shí)間戳相互轉(zhuǎn)換方法詳解,需要的朋友可以參考下
    2020-02-02
  • python趣味挑戰(zhàn)之爬取天氣與微博熱搜并自動(dòng)發(fā)給微信好友

    python趣味挑戰(zhàn)之爬取天氣與微博熱搜并自動(dòng)發(fā)給微信好友

    忙著畢設(shè)與打游戲之余,突然想著寫個(gè)爬蟲練練手,想了想,就寫了一個(gè)爬蟲爬取“中國(guó)天氣網(wǎng)”與“微博熱搜”并定時(shí)發(fā)送給微信好友,放到服務(wù)器上運(yùn)行了幾天算是正常,需要的朋友可以參考下
    2021-05-05
  • 利用Python實(shí)現(xiàn)翻譯HTML中的文本字符串

    利用Python實(shí)現(xiàn)翻譯HTML中的文本字符串

    這篇文章主要為大家介紹了如何利用Python實(shí)現(xiàn)翻譯HTML中的文本字符串功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以動(dòng)手嘗試一下
    2022-06-06

最新評(píng)論

大足县| 兴文县| 独山县| 铅山县| 红河县| 化州市| 潮州市| 天峨县| 南漳县| 虞城县| 长兴县| 新宾| 友谊县| 湖口县| 荆州市| 肥西县| 呼图壁县| 广水市| 鹤壁市| 乌兰县| 晴隆县| 东乌| 岚皋县| 天峻县| 治多县| 柘荣县| 苗栗市| 清水县| 杂多县| 辰溪县| 墨竹工卡县| 镇原县| 临邑县| 临海市| 宁国市| 德庆县| 怀来县| 古蔺县| 商南县| 岐山县| 开阳县|