亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

114 Python程序中的進程操作-進程間通信

系統 1824 0

目錄

  • 一、進程間通訊
  • 二、隊列
    • 2.1 概念介紹---multiprocessing.Queue
    • 2.2 方法介紹
    • 2.3 其他方法(了解)
  • 三、Queue隊列-實例演示
    • 3.1 但看隊列用法
    • 3.2 子進程發送數據給父進程
  • 四、生產者消費者模型
    • 4.1 為什么要使用生產者和消費者模式
    • 4.2 什么是生產者消費者模式
    • 4.3 基于隊列實現生產者消費者模型
  • 五、 JoinableQueue隊列
    • 5.1 JoinableQueue的使用
    • 5.2 通過JoinableQueue隊列實現生產者消費者模型

一、進程間通訊

IPC。就是多個進程間相互通訊。進程間通訊并不只是單個語言的問題。而是每個語言都有的。實現進程間通訊有很多。C語言中有:管道:pipe(匿名管道),有名管道、信號、共享內存、消息隊列、信號量等等

Python中這里通過隊列實現進程間通訊

二、隊列

2.1 概念介紹---multiprocessing.Queue

創建共享的進程隊列,Queue是多進程安全的隊列,可以使用Queue實現多進程之間的數據傳遞。

Queue([maxsize]) 創建共享的進程隊列。
參數 :maxsize是隊列中允許的最大項數。如果省略此參數,則無大小限制。

底層隊列使用管道和鎖定實現。

2.2 方法介紹

Queue([maxsize]) :創建共享的進程隊列。maxsize是隊列中允許的最大項數。如果省略此參數,則無大小限制。底層隊列使用管道和鎖定實現。另外,還需要運行支持進程以便隊列中的數據傳輸到底層管道中。
Queue的實例q具有以下方法:

q.get( [ block [ ,timeout ] ] ) :返回q中的一個項目。如果q為空,此方法將阻塞,直到隊列中有項目可用為止。block用于控制阻塞行為,默認為True. 如果設置為False,將引發Queue.Empty異常(定義在Queue模塊中)。timeout是可選超時時間,用在阻塞模式中。如果在制定的時間間隔內沒有項目變為可用,將引發Queue.Empty異常。

q.get_nowait() :同 q.get(False) 方法。

q.put(item [, block [,timeout ] ] ) :將item放入隊列。如果隊列已滿,此方法將阻塞至有空間可用為止。block控制阻塞行為,默認為True。如果設置為False,將引發Queue.Empty異常(定義在Queue庫模塊中)。timeout指定在阻塞模式中等待可用空間的時間長短。超時后將引發Queue.Full異常。

q.qsize() :返回隊列中目前項目的正確數量。此函數的結果并不可靠,因為在返回結果和在稍后程序中使用結果之間,隊列中可能添加或刪除了項目。在某些系統上,此方法可能引發NotImplementedError異常。

q.empty() :如果調用此方法時 q為空,返回True。如果其他進程或進程正在往隊列中添加項目,結果是不可靠的。也就是說,在返回和使用結果之間,隊列中可能已經加入新的項目。

q.full() :如果q已滿,返回為True. 由于進程的存在,結果也可能是不可靠的(參考 q.empty() 方法)。

2.3 其他方法(了解)

q.close() :關閉隊列,防止隊列中加入更多數據。調用此方法時,后臺進程將繼續寫入那些已入隊列但尚未寫入的數據,但將在此方法完成時馬上關閉。如果q被垃圾收集,將自動調用此方法。關閉隊列不會在隊列使用者中生成任何類型的數據結束信號或異常。例如,如果某個使用者正被阻塞在 get() 操作上,關閉生產者中的隊列不會導致 get() 方法返回錯誤。

q.cancel_join_thread() :不會再進程退出時自動連接后臺進程。這可以防止 join_thread() 方法阻塞。

q.join_thread() :連接隊列的后臺進程。此方法用于在調用 q.close() 方法后,等待所有隊列項被消耗。默認情況下,此方法由不是q的原始創建者的所有進程調用。調用 q.cancel_join_thread() 方法可以禁止這種行為。

三、Queue隊列-實例演示

3.1 但看隊列用法

          
            '''
ipc 進程間通訊。使用隊列實現
管道:pipe 基于共享的內存空間
隊列:pipe+鎖 Queue
put:放(可以設置阻塞非阻塞,和等待時間)
get:取(可以設置阻塞非阻塞,和等待時間)
'''
### 語法
q = Queue(3) # 創建隊列, 可以設置最大值
## put 放
q.put('你好')     # 往隊列中放入值,可以設置阻塞和等待時間,默認:滿了再放就會阻塞等待
q.put([1,2,4])
q.put(2)

### 不設置等待時間,隊列滿了繼續放
# q.put(5)    # 阻塞,隊列滿了,等待隊列空了就放進去

## get 拿
print(q.get())  # 獲取隊列中的內容,可以設置阻塞和等待時間,默認:拿不到內容就會阻塞等待
print(q.get())
print(q.get())

### 不設置等待時間
# print(q.get())  # 阻塞,一直等待獲取隊列內容

### 設置等待時間
# print(q.get(timeout=2))     # 等兩秒,等不到就報錯
# q.put(88,timeout=2)   # 不會報錯,因為隊列中沒內容


### 全都設置非阻塞模式
q = Queue(3) # 創建隊列, 可以設置最大值
q.put('你好', block=False)     # 設置非阻塞,如果滿了再放就會報錯
q.put([1,2,4], block=False)
q.put(2, block=False)
# q.put(4, block=False)       # 報錯,隊列滿了

# q.put_nowait('666') # 等同 block = False,報錯,隊列滿了
          
        

3.2 子進程發送數據給父進程

          
            import time
from multiprocessing import Process, Queue

def f(q):
    q.put([time.asctime(), 'from Eva', 'hello'])  #調用主函數中p進程傳遞過來的進程參數 put函數為向隊列中添加一條數據。

if __name__ == '__main__':
    q = Queue() #創建一個Queue對象
    p = Process(target=f, args=(q,)) #創建一個進程
    p.start()
    print(q.get())
    p.join()
          
        

上面是一個queue的簡單應用,使用隊列q對象調用get函數來取得隊列中最先進入的數據。 接下來看一個稍微復雜一些的例子:批量生產數據放入隊列再批量獲取結果。

四、生產者消費者模型

在并發編程中使用生產者和消費者模式能夠解決絕大多數并發問題。該模式通過平衡生產進程和消費進程的工作能力來提高程序的整體處理數據的速度。

4.1 為什么要使用生產者和消費者模式

在進程世界里,生產者就是生產數據的進程,消費者就是消費數據的進程。在多進程開發當中,如果生產者處理速度很快,而消費者處理速度很慢,那么生產者就必須等待消費者處理完,才能繼續生產數據。同樣的道理,如果消費者的處理能力大于生產者,那么消費者就必須等待生產者。為了解決這個問題于是引入了生產者和消費者模式。

4.2 什么是生產者消費者模式

生產者消費者模式是通過一個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通訊,而通過阻塞隊列來進行通訊,所以生產者生產完數據之后不用等待消費者處理,直接扔給阻塞隊列,消費者不找生產者要數據,而是直接從阻塞隊列里取,阻塞隊列就相當于一個緩沖區,平衡了生產者和消費者的處理能力。

4.3 基于隊列實現生產者消費者模型

          
            ef producer(q,name,food):
    '''生產者'''
    for i in range(10):
        print(f'{name}生產了{food}{i}')
        res = f'{food}{i}'
        q.put(res)


def consumer(q,name):
    '''消費者'''
    while 1:
        res = q.get()
        if res == None:
            break
        print(f'{name}買了{res}')


if __name__ == '__main__':
    q = Queue()   # 使用隊列
    p1 = Process(target=producer,args=(q,"xc","意大利面"))
    c1 = Process(target=consumer,args=(q,"haha"))
    p2 = Process(target=producer, args=(q, "xc", "牛肉"))
    c2 = Process(target=consumer, args=(q, "xixi"))
    p3 = Process(target=producer, args=(q, "xc", "可樂"))
    p1.start()
    c1.start()
    p2.start()
    c2.start()
    p3.start()

    p1.join()   # 等待生產者結束
    p2.join()   # 等待生產者結束
    p3.join()   # 等待生產者結束

    q.put(None) # 有幾個消費者就要發幾個None,讓 子進程收到None就結束
    q.put(None) # 有幾個消費者就要發幾個None,讓 子進程收到None就結束
          
        

結束信號None,不一定要由生產者發,主進程里同樣可以發,但主進程需要等生產者結束后才應該發送該信號。 有幾個消費者就要發幾個None,讓 子進程收到None就結束

五、 JoinableQueue隊列

JoinableQueue隊列就對Queue隊列的改良版,加入了類似信號量的機制。

5.1 JoinableQueue的使用

語法:

  1. 實例化對象: q = JoinableQueue()
  2. 向隊列中放入內容,相當于 信號量+1 操作: q.put(xxx)
  3. 從隊列中取出內容: q.get()
  4. 任務結束,相當于 信號量-1 操作: q.task_done()
  5. 當這個 信號量不為0時,會阻塞等待,計數器為0后通過。

實例:

          
            # JoinableQueue的使用
q = JoinableQueue()

q.put('1')  # +1
q.put('2')  # +1

print(q.get())
q.task_done()   # -1    
print(q.get())
q.task_done()  # -1
q.join() #計數器不為0會阻塞等待 計數器為0后通過
          
        

5.2 通過JoinableQueue隊列實現生產者消費者模型

          
            def producer(q, name, food):
    '''生產者'''
    for i in range(10):
        print(f'{name}生產了{food}{i}')
        res = f'{food}{i}'
        q.put(res)  # +1


def consumer(q, name):
    '''消費者'''
    while 1:
        res = q.get()
        if res == None:
            break
        print(f'{name}買了{res}')
        q.task_done()


if __name__ == '__main__':
    q = JoinableQueue()     # 使用加了join的隊列
    p1 = Process(target=producer, args=(q, "xc", "意大利面"))
    c1 = Process(target=consumer, args=(q, "haha"))
    p2 = Process(target=producer, args=(q, "xc", "牛肉"))
    c2 = Process(target=consumer, args=(q, "xixi"))
    p3 = Process(target=producer, args=(q, "xc", "可樂"))
    # 把消費者變成守護進程,主進程結束,子進程就結束
    c1.daemon = True    # 進程結束,子進程就結束
    c2.daemon = True    # 進程結束,子進程就結束

    p1.start()
    c1.start()
    p2.start()
    c2.start()
    p3.start()

    p1.join()  # 等待生產者結束
    p2.join()  # 等待生產者結束
    p3.join()  # 等待生產者結束
          
        

上述代碼中,是 通過將子進程變為守護進程 ,在消費者的子進程中 每次收到消息都task_done ,然后 等待主進程結束,直接結束子進程


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 免费欧洲毛片a级视频老妇女 | 欧美线人一区二区三区 | 欧美国产成人精品一区二区三区 | 日日添天天做天天爱 | 亚洲国产麻豆 | 日韩在线看片中文字幕不卡 | 国产成人精品2021欧美日韩 | 欧美福利视频在线 | 国产91成人精品亚洲精品 | 四虎影院在线免费播放 | 一区二区三区网站在线免费线观看 | 最近中文字幕无免费视频 | 亚洲精品国产综合久久一线 | 99热在这里只有免费精品 | 精品久久久久久午夜 | 夜夜超b天天 | 天天爽天天狼久久久综合 | 国产色婷婷精品综合在线 | 久久99国产精品久久 | 真人特级毛片免费视频 | 99免费视频 | 国产情侣久久精品 | 国产高清一级毛片在线不卡 | 亚洲精品国产不卡在线观看 | 天天操91| 爱做久久久久久久久久 | 日韩亚洲欧美在线观看 | 国产大片在线观看 | 高清欧美一级在线观看 | 国内精品久久久久久西瓜色吧 | 午夜欧美福利视频 | 久久成人免费视频 | 成人国产一区二区三区精品 | 亚洲香蕉在线视频 | 91成人爽a毛片一区二区 | 久久免费看 | 久久一区二区三区精品 | 国外免费一级 | 牛牛影视免费观看成人 | 国内精品51视频在线观看 | 欧美日韩亚洲国内综合网香蕉 |