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()
說明: