在使用Python多線程的時候,在使用多線程編程的時候,因爲對於變量做用域和多線程不是很熟悉,致使在使用多線程的時候,犯了低級的錯誤。html
第一個錯誤:python
在多線程中使用全局變量,致使多個線程修改全局變量。執行信息錯亂,開始是幾個個進程,後面就變成一個了。後來通過從新學習多線程,才把原來的錯誤修改過來。編程
腳本功能,多線程向設備上傳和下載文件,測試ftp功能和性能。錯誤緣由是把ftp變量設置爲了全局變量,致使出現怪異的現象,開始有幾個線程在跑,而後幾個進程退出,最後變爲一個,還出現了ftp密碼錯誤的提示。當時調試了很久,後來使用pycharm工具,觀察到了問題的緣由。網絡
代碼以下:多線程
紅色的代碼爲錯誤的版本,最初的時候,ftp變量在外面,做爲全局變量使用。綠色的代碼爲修改正確的版本。函數
#! /usr/bin/env python #coding=utf-8 from ftplib import FTP from datetime import datetime import sys import os import threading FTP_Port='21' Telnet_Port='23' buffsize=1024 #ftp=FTP() class ftp_test(threading.Thread): upload_dir="../upload/" download_dir="../download" IP ='' Username='' Password='' def __init__(self,env_para): threading.Thread.__init__(self) self.IP=env_para['IP_Addr'] self.Password= env_para['Password'] self.Username= env_para['admin'] self.upload_dir= env_para['upload_dir'] self.download_dir= env_para['download_dir'] def ftp_upload(self,tfile): ftp=FTP() ftp.connect(self.IP, FTP_Port,timeout=10) ftp.login(self.Username,self.Password) #print ftp.getwelcome() ftp.cwd(ramdisk) #print ftp.dir() file_handler=open(self.upload_dir + tfile,'rb') ftp.storbinary('STOR '+ tfile ,file_handler,buffsize) #ftp.dir() file_handler.close() ftp.quit() print tfile,' Upload OK' def ftp_download(self,t_file): ftp=FTP() ftp.connect(self.IP, FTP_Port,timeout=10) #ftp.set_debuglevel(2) ftp.login(self.Username,self.Password) filename = t_file +'_download' file_write=open( self.download_dir + filename,'wb').write ftp.retrbinary('RETR '+ filename, file_write, buffsize) ftp.delete(filename) ftp.quit() print t_file,' FTP download OK' def run(self): file_list=os.listdir(self.upload_dir) for each_file in file_list: try: self.ftp_upload(each_file) except Exception ,e: print each_file ,' FTP Upload fail' print e try: self.ftp_download(each_file) except Exception ,e: print each_file ,' FTP download fail' print e
這樣在函數中定義,縮小了ftp變量的做用域,終於完成了ftp並行的上傳和下載。工具
定位過程:性能
在使用pycharm調試時,觀察ftp變量的變化,發現只有一個ftp變量,全部的進程都使用的是這一個變量,ftp變量記錄的ftp狀態不斷在變化,出現了各類奇怪的現象。學習
在縮小了ftp變量的做用域後,從新調試,觀察到ftp變量在每一個進行中的地址都不同,每一個ftp的變化不受其餘進程影響。測試
第二個錯誤:
由於在網絡上學習分享的多線程文章,受 http://www.cnblogs.com/fnng/p/3670789.html 這個分享的影響,在線程啓動後,直接寫了t.join(),不是把全部的進程都加了join。
致使執行慢的進程被主線程直接終止,出現了屢次ftp沒有執行完成,線程就退出。
正確的寫法是:
for t in threads:
t.join()
這個分析當時把我害苦了,調試了老半天才發現這個錯誤。
總結心得:
對於學習仍是要看書籍系統的學習。
另外,學會使用工具調試,觀察變量的變化,深刻理解程序運行,方便定位問題。