zoukankan      html  css  js  c++  java
  • 使用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的变化不受其他进程影响。

    第二个错误:

    因为在网络上学习分享的多线程文章,受 http://www.cnblogs.com/fnng/p/3670789.html 这个分享的影响,在线程启动后,直接写了t.join(),不是把所有的进程都加了join。

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

    正确的写法是:

    for t in threads:

      t.join()

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

    总结心得:

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

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

  • 相关阅读:
    51Nod 1016 水仙花数 V2(组合数学,枚举打表法)
    April Fools Contest 2017 题解&源码(A,数学 B,数学 C,数学 D,字符串 E,数字逻辑 F,排序,卡时间,G,数学)
    统计0到n之间1的个数[数学,动态规划dp](经典,详解)
    hihoCoder #1082 : 然而沼跃鱼早就看穿了一切(字符串处理)
    洛谷 P1876 开灯(思维,枚举,规律题)
    Codeforces 789A Anastasia and pebbles(数学,思维题)
    51Nod 1182 完美字符串(字符串处理 贪心 Facebook Hacker Cup选拔)
    机器学习(Machine Learning)&深度学习(Deep Learning)资料
    看一下你在中国属于哪个阶层?
    python读取mnist
  • 原文地址:https://www.cnblogs.com/StitchSun/p/4256525.html
Copyright © 2011-2022 走看看