PYTHON的线程

 

一、线程

例:

                  import threading

                  import time

                  def run(num):

                      print ("thread...",num)

                    time.sleep(1)

                  for i in range(100):

                      t = threading.Thread(target=run,args =(i,))

                      t.start()

                 

         上面的例子建了十个线程,虚拟机解析之后将它们交给CPU执行,但它们并不是真正的多线程,而且根据一定的算法,分片执行,由于执行速度非常快,所以感觉像是并行

         thread类的方法有:

         start            线程准备就绪,等待CPU调度

         setName      为线程设置名称

         getName      获取线程名称

         setDaemon   设置为后台线程或前台线程(默认)

                   如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执                                         行完毕后,后台线程不论成功与否,均停止

                    如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执                              行完毕后,等待前台线程也执行完成后,程序停止

         join               逐个执行每个线程,执行完毕后继续往下执行...

         run              线程被cpu调度后执行此方法

 

二、线程锁

         当多个线程都去修改一个变量时,有可能线程a取到变量值修改后还没返回时,线程b也拿到这个变量去修改,这样会导致变量的结果与期望的不一样,这时,就需要用锁来保证这个变量同时只能由一个线程来更改

         import threading

         import time

 

         gl_num = 0

         lock = threading.RLock()

 

         def Func():

             lock.acquire()

             global gl_num

             gl_num +=1

             time.sleep(1)

             print gl_num

             lock.release()

     

         for i in range(10):

             t = threading.Thread(target=Func)

             t.start()

 

三、PYTHON的多线程为何不是并发的

         GIL—Global interpreter lock

         线程锁保护与GIL有什么不同?

 

FTP练习,编程的一些规范

  1. 建目录 bin module var conf

根据文件的作用来分目录存放

  1. MVC---module        views       controller

  2. 多使用面向对象来编程,尽量脱离面向过程

用到的知识点

  1. 入口文件里并不执行真正的程序,只有一个入口指向实现功能的文件里的类

  2. 使用hasattr  getattr来代替if else

  3. 如果要使用当前文件的属性,hasattr(sys.modules[__name__],'class_a')hasattr(__import__[__name__],attribute)

  4. 服务端当用户验证通过后,要保证接下来的连接用户已经验证通过,设置变量self.username = username

  5. 进度条,每0.2秒打印一个#,在一行,共打印40

for I in range(40):

         sys.stdout.write(‘#’)

         sys.stdout.flush()

          time.sleep(0.2)

 for i in range(40):   #这个会打印百分比,并且在同一个位置不断变化(\r的作用)

sys.stdout.write('\r%d%%' %i) 

sys.stdout.flush()

    time.sleep(0.2)

 

                  sys.stdout.flush()   的作用

                  stdout是有缓冲区的,如果没有flush,那么输出可能会在全部执行完后再打印

                  flush会将已在缓冲区的推到终端,这样就能立即输出(没测试出来)

  1. while….: … else:… 

while里的循环正常结束后,执行else里的代码,如果循环非正常结束,比如break,则不执行,countinue是正常循环

  1. 对文件进行MD5验证

在文件传输时,在每个循环里进行md5运算,而不是单独对整个文件进行md5

f = open(file_abs_path,"rb")

file_md5 = hashlib.md5()

while file_size != sent_size:

    data = f.read(4096)

    self.request.send(data)

    sent_size += len(data)

    file_md5.update(data)

    print("send:",file_size,sent_size)

else:

        md5_str = file_md5.hexdigest()

 

  1. 当修改远程的目录时,不要在服务器端真的执行chdir,这样会修改了整个服务端进程的目录,影响了别的客户端,而是设一个目录变量,每次修改这个目录变量,然后这个变量来取相关结果