程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL長途銜接喪失成績處理辦法(Lost connection to MySQL server)

MySQL長途銜接喪失成績處理辦法(Lost connection to MySQL server)

編輯:MySQL綜合教程

MySQL長途銜接喪失成績處理辦法(Lost connection to MySQL server)。本站提示廣大學習愛好者:(MySQL長途銜接喪失成績處理辦法(Lost connection to MySQL server))文章只能為提供參考,不一定能成為您想要的結果。以下是MySQL長途銜接喪失成績處理辦法(Lost connection to MySQL server)正文


我們將應用Python線程來處理Python中的臨盆者—花費者成績。這個成績完整不像他們在黉捨中說的那末難。

假如你對臨盆者—花費者成績有懂得,看這篇博客會更成心義。

為何要關懷臨盆者—花費者成績:

  •     可以幫你更好地輿解並發和分歧概念的並發。
  •     信息隊列中的完成中,必定水平上應用了臨盆者—花費者成績的概念,而你某些時刻必定會用到新聞隊列。

當我們在應用線程時,你可以進修以下的線程概念:

  •     Condition:線程中的前提。
  •     wait():在前提實例中可用的wait()。
  •     notify() :在前提實例中可用的notify()。

我假定你曾經有這些根本概念:線程、競態前提,和若何處理靜態前提(例如應用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

說明:

  •     我們開端了一個臨盆者線程(下稱臨盆者)和一個花費者線程(下稱花費者)。
  •     臨盆者一直地添加(數據)到隊列,而花費者一直地消費。
  •     因為隊列是一個同享變量,我們把它放到lock法式塊內,以防產生競態前提。
  •     在某一時光點,花費者把一切器械消費終了而臨盆者還在掛起(sleep)。花費者測驗考試持續停止消費,但此時隊列為空,湧現IndexError異常。
  •     在每次運轉進程中,在產生IndexError異常之前,你會看到print語句輸入”Nothing in queue, but consumer will try to consume”,這是你失足的緣由。

我們把這個完成作為毛病行動(wrong behavior)。

甚麼是准確行動?

當隊列中沒有任何數據的時刻,花費者應當停滯運轉並期待(wait),而不是持續測驗考試停止消費。而當臨盆者在隊列中參加數據以後,應當有一個渠道去告知(notify)花費者。然後花費者可以再次從隊列中停止消費,而IndexError不再湧現。

關於前提

    前提(condition)可讓一個或多個線程進入wait,直到被其他線程notify。參考:?http://docs.python.org/2/library/threading.html#condition-objects

這就是我們所須要的。我們願望花費者在隊列為空的時刻wait,只要在被臨盆者notify後恢復。臨盆者只要在往隊列中參加數據落後行notify。是以在臨盆者notify後,可以確保隊列非空,是以花費者花費時不會湧現異常。

  •     condition內含lock。
  •     condition有acquire()和release()辦法,用以挪用外部的lock的對應辦法。

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

說明:

  •     關於花費者,在花費前檢討隊列能否為空。
  •     假如為空,挪用condition實例的wait()辦法。
  •     花費者進入wait(),同時釋放所持有的lock。
  •     除非被notify,不然它不會運轉。
  •     臨盆者可以acquire這個lock,由於它曾經被花費者release。
  •     當挪用了condition的notify()辦法後,花費者被叫醒,但叫醒不料味著它可以開端運轉。
  •     notify()其實不釋放lock,挪用notify()後,lock仍然被臨盆者所持有。
  •     臨盆者經由過程condition.release()顯式釋放lock。
  •     花費者再次開端運轉,如今它可以獲得隊列中的數據而不會湧現IndexError異常。

為隊列增長年夜小限制

臨盆者不克不及向一個滿隊列持續參加數據。

它可以用以下方法來完成:

  •     在參加數據前,臨盆者檢討隊列能否為滿。
  •     假如不為滿,臨盆者可以持續正常流程。
  •     假如為滿,臨盆者必需期待,挪用condition實例的wait()。
  •     花費者可以運轉。花費者消費隊列,並發生一個空余地位。
  •     然後花費者notify臨盆者。
  •     當花費者釋放lock,花費者可以acquire這個lock然後往隊列中參加數據。

終究法式以下:

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()

說明:

  •     在本來應用list的地位,改成應用Queue實例(下稱隊列)。
  •     這個隊列有一個condition,它有本身的lock。假如你應用Queue,你不須要為condition和lock而懊惱。
  •     臨盆者挪用隊列的put辦法來拔出數據。
  •     put()在拔出數據前有一個獲得lock的邏輯。
  •     同時,put()也會檢討隊列能否已滿。假如已滿,它會在外部挪用wait(),臨盆者開端期待。
  •     花費者應用get辦法。
  •     get()從隊列中移出數據前會獲得lock。
  •     get()會檢討隊列能否為空,假如為空,花費者進入期待狀況。
  •     get()和put()都有恰當的notify()。如今就去看Queue的源碼吧。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved