设为首页 加入收藏

TOP

使用Python多线程犯的错误总结
2015-07-16 12:55:47 来源: 作者: 【 】 浏览:23
Tags:使用 Python 线程 错误 总结

在使用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的变化不受其他进程影响。


第二个错误:


导致执行慢的进程被主线程直接终止,出现了多次ftp没有执行完成,线程就退出。


正确的写法是:


for t in threads:


  t.join()


使用Python多线程犯的错误总结


这个分析当时把我害苦了,调试了老半天才发现这个错误。


总结心得:


对于学习还是要看书籍系统的学习。


另外,学会使用工具调试,观察变量的变化,深入理解程序运行,方便定位问题。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Python 多线程就这么简单 下一篇如何用Android Studio打多包名APK

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: