python程式中,在程序和程序之間是不共享全域性變數的資料的。
我們來看乙個例子:
from multiprocessing import process
import os
import time
nums = [11, 22]
def work1():
"""子程序要執行的**"""
print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
for i in range(3):
time.sleep(1)
print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
def work2():
"""子程序要執行的**"""
print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))
if __name__ == '__main__':
p1 = process(target=work1)
p1.start()
p1.join()
p2 = process(target=work2)
p2.start()
程序 p1 裡對全域性變數 nums 迴圈進行處理,程序 p2 將 nums 列印出來,發現 nums 的值沒有變化。
執行結果:
in process1 pid=5788 ,nums=[11, 22]
in process1 pid=5788 ,nums=[11, 22, 0]
in process1 pid=5788 ,nums=[11, 22, 0, 1]
in process1 pid=5788 ,nums=[11, 22, 0, 1, 2]
in process2 pid=11832 ,nums=[11, 22]
通過佇列完成程序間通訊
但是程序(process)之間有時需要通訊,作業系統提供了很多機制來實現程序間的通訊。
可以使用 multiprocessing 模組的 queue 實現多程序之間的資料傳遞。
queue 本身是乙個訊息佇列程式,首先用乙個小例項來演示一下 queue 的工作原理:
from multiprocessing import queue
# 初始化乙個queue物件,最多可接收三條put訊息
q = queue(3)
q.put("訊息1")
q.put("訊息2")
print(q.full()) # false
q.put("訊息3")
print(q.full()) # true
# 因為訊息佇列已滿下面的try都會丟擲異常
# 第乙個try會等待2秒後再丟擲異常
try:
q.put("訊息4", true, 2)
except:
print("訊息佇列已滿,現有訊息數量:%s" % q.qsize())
# 第二個try會立刻丟擲異常
try:
q.put_nowait("訊息4")
except:
print("訊息列隊已滿,現有訊息數量:%s" % q.qsize())
# 推薦的方式,先判斷訊息列隊是否已滿,再寫入
if not q.full():
q.put_nowait("訊息4")
# 讀取訊息時,先判斷訊息列隊是否為空,再讀取
if not q.empty():
for i in range(q.qsize()):
print(q.get_nowait())
執行結果:
佇列 queue 的使用說明
初始化 queue()物件時(例如:q=queue()),若括號中沒有指定最大可接收的訊息數量,或數量為負值,那麼就代表可接受的訊息數量沒有上限(直到記憶體的盡頭)。
queue.qsize():返回當前佇列包含的訊息數量。
queue.empty():如果隊列為空,返回true,反之false。
queue.full():如果佇列滿了,返回true,反之false。
queue.get([block[, timeout]]):獲取佇列中的一條訊息,然後將其從列隊中移除,block 預設值為 true。
如果 block 使用預設值,且沒有設定 timeout(單位秒),訊息佇列如果為空,此時程式將被阻塞,停在讀取狀態,直到從訊息佇列讀到訊息為止;如果設定了 timeout,則會等待 timeout 秒,若還沒讀取到任何訊息,則丟擲 "queue.empty" 異常。
如果 block 值為 false,訊息列隊如果為空,則會立刻丟擲 "queue.empty" 異常。
queue.get_nowait():相當 queue.get(false)。
queue.put(item,[block[, timeout]]):將 item 訊息寫入佇列,block 預設值為 true。
如果 block 使用預設值,且沒有設定 timeout(單位秒),訊息佇列如果已經沒有空間可寫入,此時程式將被阻塞,停在寫入狀態,直到從訊息佇列騰出空間為止;如果設定了timeout,則會等待 timeout 秒,若還沒空間,則丟擲 "queue.full" 異常。
如果 block 值為 false,訊息佇列如果沒有空間可寫入,則會立刻丟擲 "queue.full" 異常。
queue.put_nowait(item):相當queue.put(item, false)。
queue例項
我們以 queue 為例,在父程序中建立兩個子程序,乙個往 queue 裡寫資料,乙個從 queue 裡讀資料。
from multiprocessing import process, queue
import os
import time
import random
def write(q):
# 寫資料程序執行的**:
for value in ['a', 'b', 'c']:
print('put %s to queue...' % value)
q.put(value)
time.sleep(random.random())
def read(q):
# 讀資料程序執行的**:
while true:
if not q.empty():
value = q.get(true)
print('get %s from queue.' % value)
time.sleep(random.random())
else:
break
if __name__ == '__main__':
# 父程序建立queue,並傳給各個子程序:
q = queue()
pw = process(target=write, args=(q,))
pr = process(target=read, args=(q,))
# 啟動子程序pw,寫入:
pw.start()
# 等待pw結束:
pw.join()
# 啟動子程序pr,讀取:
pr.start()
pr.join()
print('')
print('所有資料都寫入並且讀完')
執行結果:
Python 中通過佇列來實現程序間通訊
python程式中,在程序和程序之間是不共享全域性變數的資料的。我們來看乙個例子 from multiprocessing import process import os import time nums 11 22 def work1 子程序要執行的 print in process1 pid ...
Unity中通過PlayerPrefs進行資料儲存
在unity中儲存資料也是通過鍵值對的方式來進行。主要通過playerprefs來完成。通過playerprefs可以用來儲存和訪問玩家的偏好設定。在mac os x中,playerprefs的資料儲存在 library preferences資料夾中,以unity.company name pro...
在Sqlite中通過Replace來實現插入和更新
你可能在批量處理乙個事務的時候,想要批量插入一系列的資料,但是這些資料當新增完一次之後,重新新增的時候,你不想要重新新增,只是想將原有的資料進行更新,例如 我想要通過excel將一系列的圖書匯入到資料庫中,而這些圖書在你下一次編輯之後,重新匯入,只是對原有的資料進行修改。以上是乙個業務的場景。在ms...