MySQL長途銜接喪失成績處理辦法(Lost connection to MySQL server)。本站提示廣大學習愛好者:(MySQL長途銜接喪失成績處理辦法(Lost connection to MySQL server))文章只能為提供參考,不一定能成為您想要的結果。以下是MySQL長途銜接喪失成績處理辦法(Lost connection to MySQL server)正文
我們將應用Python線程來處理Python中的臨盆者—花費者成績。這個成績完整不像他們在黉捨中說的那末難。
假如你對臨盆者—花費者成績有懂得,看這篇博客會更成心義。
為何要關懷臨盆者—花費者成績:
當我們在應用線程時,你可以進修以下的線程概念:
我假定你曾經有這些根本概念:線程、競態前提,和若何處理靜態前提(例如應用lock)。不然的話,你建議你去看我上一篇文章basics of Threads。
援用維基百科:
臨盆者的任務是發生一塊數據,放到buffer中,如斯輪回。與此同時,花費者在消費這些數據(例如從buffer中把它們移除),每次一塊。
這裡的症結詞是“同時”。所以臨盆者和花費者是並發運轉的,我們須要對臨盆者和花費者做線程分別。
from threading import Thread class ProducerThread(Thread): def run(self): pass class ConsumerThread(Thread): def run(self): pass
再次援用維基百科:
這個為描寫了兩個同享固定年夜小緩沖隊列的過程,即臨盆者和花費者。
假定我們有一個全局變量,可以被臨盆者和花費者線程修正。臨盆者發生數據並把它參加到隊列。花費者消費這些數據(例如把它移出)。
queue = []
在剛開端,我們不會設置固定年夜小的前提,而在現實運轉時參加(指下述例子)。
一開端帶bug的法式:
from threading import Thread, Lock import time import random queue = [] lock = Lock() class ProducerThread(Thread): def run(self): nums = range(5) #Will create the list [0, 1, 2, 3, 4] global queue while True: num = random.choice(nums) #Selects a random number from list [0, 1, 2, 3, 4] lock.acquire() queue.append(num) print "Produced", num lock.release() time.sleep(random.random()) class ConsumerThread(Thread): def run(self): global queue while True: lock.acquire() if not queue: print "Nothing in queue, but consumer will try to consume" num = queue.pop(0) print "Consumed", num lock.release() time.sleep(random.random()) ProducerThread().start() ConsumerThread().start()
運轉幾回並留心一下成果。假如法式在IndexError異常後並沒有主動停止,用Ctrl+Z停止運轉。
樣例輸入:
Produced 3 Consumed 3 Produced 4 Consumed 4 Produced 1 Consumed 1 Nothing in queue, but consumer will try to consume Exception in thread Thread-2: Traceback (most recent call last): File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner self.run() File "producer_consumer.py", line 31, in run num = queue.pop(0) IndexError: pop from empty list
說明:
我們把這個完成作為毛病行動(wrong behavior)。
甚麼是准確行動?
當隊列中沒有任何數據的時刻,花費者應當停滯運轉並期待(wait),而不是持續測驗考試停止消費。而當臨盆者在隊列中參加數據以後,應當有一個渠道去告知(notify)花費者。然後花費者可以再次從隊列中停止消費,而IndexError不再湧現。
關於前提
前提(condition)可讓一個或多個線程進入wait,直到被其他線程notify。參考:?http://docs.python.org/2/library/threading.html#condition-objects
這就是我們所須要的。我們願望花費者在隊列為空的時刻wait,只要在被臨盆者notify後恢復。臨盆者只要在往隊列中參加數據落後行notify。是以在臨盆者notify後,可以確保隊列非空,是以花費者花費時不會湧現異常。
condition的acquire()和release()辦法外部挪用了lock的acquire()和release()。所以我們可以用condiction實例代替lock實例,但lock的行動不會轉變。
臨盆者和花費者須要應用統一個condition實例, 包管wait和notify正常任務。
重寫花費者代碼:
from threading import Condition condition = Condition() class ConsumerThread(Thread): def run(self): global queue while True: condition.acquire() if not queue: print "Nothing in queue, consumer is waiting" condition.wait() print "Producer added something to queue and notified the consumer" num = queue.pop(0) print "Consumed", num condition.release() time.sleep(random.random())
重寫臨盆者代碼:
class ProducerThread(Thread): def run(self): nums = range(5) global queue while True: condition.acquire() num = random.choice(nums) queue.append(num) print "Produced", num condition.notify() condition.release() time.sleep(random.random())
樣例輸入:
Produced 3 Consumed 3 Produced 1 Consumed 1 Produced 4 Consumed 4 Produced 3 Consumed 3 Nothing in queue, consumer is waiting Produced 2 Producer added something to queue and notified the consumer Consumed 2 Nothing in queue, consumer is waiting Produced 2 Producer added something to queue and notified the consumer Consumed 2 Nothing in queue, consumer is waiting Produced 3 Producer added something to queue and notified the consumer Consumed 3 Produced 4 Consumed 4 Produced 1 Consumed 1
說明:
為隊列增長年夜小限制
臨盆者不克不及向一個滿隊列持續參加數據。
它可以用以下方法來完成:
終究法式以下:
from threading import Thread, Condition import time import random queue = [] MAX_NUM = 10 condition = Condition() class ProducerThread(Thread): def run(self): nums = range(5) global queue while True: condition.acquire() if len(queue) == MAX_NUM: print "Queue full, producer is waiting" condition.wait() print "Space in queue, Consumer notified the producer" num = random.choice(nums) queue.append(num) print "Produced", num condition.notify() condition.release() time.sleep(random.random()) class ConsumerThread(Thread): def run(self): global queue while True: condition.acquire() if not queue: print "Nothing in queue, consumer is waiting" condition.wait() print "Producer added something to queue and notified the consumer" num = queue.pop(0) print "Consumed", num condition.notify() condition.release() time.sleep(random.random()) ProducerThread().start() ConsumerThread().start()
樣例輸入:
Produced 0 Consumed 0 Produced 0 Produced 4 Consumed 0 Consumed 4 Nothing in queue, consumer is waiting Produced 4 Producer added something to queue and notified the consumer Consumed 4 Produced 3 Produced 2 Consumed 3
更新:
許多網友建議我在lock和condition下應用Queue來取代應用list。我贊成這類做法,但我的目標是展現Condition,wait()和notify()若何任務,所以應用了list。
以下用Queue來更新一下代碼。
Queue封裝了Condition的行動,如wait(),notify(),acquire()。
如今不掉為一個好機遇讀一下Queue的文檔(http://docs.python.org/2/library/queue.html)。
更新法式:
from threading import Thread import time import random from Queue import Queue queue = Queue(10) class ProducerThread(Thread): def run(self): nums = range(5) global queue while True: num = random.choice(nums) queue.put(num) print "Produced", num time.sleep(random.random()) class ConsumerThread(Thread): def run(self): global queue while True: num = queue.get() queue.task_done() print "Consumed", num time.sleep(random.random()) ProducerThread().start() ConsumerThread().start()
說明: