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练习,编程的一些规范
建目录 bin module var conf
根据文件的作用来分目录存放
MVC---module views controller
多使用面向对象来编程,尽量脱离面向过程
用到的知识点
入口文件里并不执行真正的程序,只有一个入口指向实现功能的文件里的类
使用hasattr getattr来代替if else
如果要使用当前文件的属性,hasattr(sys.modules[__name__],'class_a')或hasattr(__import__[__name__],attribute)
服务端当用户验证通过后,要保证接下来的连接用户已经验证通过,设置变量self.username = username
进度条,每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会将已在缓冲区的推到终端,这样就能立即输出(没测试出来)
while….: … else:…
while里的循环正常结束后,执行else里的代码,如果循环非正常结束,比如break,则不执行,countinue是正常循环
对文件进行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()
当修改远程的目录时,不要在服务器端真的执行chdir,这样会修改了整个服务端进程的目录,影响了别的客户端,而是设一个目录变量,每次修改这个目录变量,然后这个变量来取相关结果