Python学习笔记Day09 - 多线程
目录
http://www.cnblogs.com/alex3714/articles/5230609.html
1.paramiko 基于SSH用于连接远程服务器并执行相关操作
# http://www.cnblogs.com/wupeiqi/articles/5095821.html
import paramiko
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='c1.salt.com', port=22, username='wupeiqi', password='123')
# # 利用RSA私钥登录
# private_key = paramiko.RSAKey.from_private_key_file('id_rsa31')
# ssh.connect(hostname='10.0.0.41', port=52113, username='gongli', pkey=private_key)
# 执行命令,返回三个结果:标准输入,标准输出,标准错误
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果,输出或者错误
res,err = stdout.read(),stderr.read()
result = res if res else err
print(result.decode())
# 关闭连接
ssh.close()
2.SSH与SFTP,通过paramiko执行命令,或传输文件
# 上传下载文件
import paramiko
transport = paramiko.Transport(('10.0.0.31', 52113)) # 创建
transport.connect(username='root', password='123456') # 建立连接
sftp = paramiko.SFTPClient.from_transport(transport) # 将连接交给SFTP客户端处理
# 将location.py 上传至服务器 /tmp/test.py
sftp.put('笔记', '/tmp/test_from_win')
# 将remove_path 下载到本地 local_path
sftp.get('/root/oldgirl.txt', 'fromlinux.txt')
transport.close()
3.ssh 密钥
RSA -非对称密钥验证
公钥 public key (天王盖地虎)
私钥 private key (宝塔镇河妖)
10.0.0.31 -----> 10.0.0.41
私钥 公钥
4.进程和线程
进程: qq 要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用,
内存的管理,网络接口的调用等。。。对各种资源管理的集合 就可以称为进程
线程: 是操作系统最小的调度单位, 是一串指令的集合
线程可以创建同级线程
进程要操作cpu , 必须要先创建一个线程
进程是一系列线程的集合,可以创建子进程,同一进程内的线程共享同一块内存空间的数据
进程与线程的区别?
1.线程共享内存空间;进程的内存是独立的
2.同一个进程的线程之间可以直接交流;两个进程想通信,必须通过一个中间代理来实现
3.创建新线程很简单;创建新进程需要对其父进程进行一次克隆,生成之后的二者独立
4.一个线程可以控制和操作同一进程里的其他线程;但是进程只能操作子进程
5.改变进程里的一个线程可能对另一个线程有影响;但父进程修改对子进程无影响
5.threading 多线程
join 等待
Daemon 守护线程
# 创建多线程
# join
# daemon
import threading
import time
def run(n):
print("task ", n)
time.sleep(2)
print("task done", n)
start_time = time.time()
# t1 = threading.Thread(target=run, args=("t-1",))
# t2 = threading.Thread(target=run, args=("t-2",))
# 批量启动大量线程
t_objs = [] # 存线程实例
for i in range(50):
t = threading.Thread(target=run, args=("t-%s" % i,)) # 循环创建线程实例
# 守护线程,当主线程退出时,守护线程也会退出,由t启动的其它子线程会同时退出,不管是否执行完任务
t.setDaemon(True) # 守护线程设置一定要在start之前
t.start() # 启动线程
t_objs.append(t) # 为了不阻塞后面线程的启动,不在这里join,先放到一个列表里
# 正常情况下,主线程启动了子线程后,主线程独立运行,不等待子线程执行完毕
# 利用join等待某线程执行完毕主线程再继续(有些语言是wait())
for t in t_objs: # 循环线程实例列表,等待所有线程执行完毕
t.join()
print("----------all threads has finished...")
print("cost:", time.time() - start_time)
用类的形式创建线程,继承式调用(一般不用)
import threading
import time
class MyThread(threading.Thread):
def __init__(self, n, sleep_time):
super(MyThread, self).__init__()
self.n = n
self.sleep_time = sleep_time
def run(self):
print("runnint task ", self.n)
time.sleep(self.sleep_time)
print("task done,", self.n)
t1 = MyThread("t1", 2)
t2 = MyThread("t2", 4)
t1.start()
t2.start()
t1.join() # =wait()
t2.join()
print("main thread....")
GIL vs lock
lock 线程锁(mutex互斥锁) 保证同一时间只有一个线程修改数据
# 线程lock,2.*上需要自己加,3.*上自动加
# 保证同一时间只有一个线程在修改数据
import threading
import time
def run(n):
lock.acquire() # 获取锁
global num
num += 1
time.sleep(1)
lock.release() # 释放线程锁
lock = threading.Lock() # 申请线程锁
num = 0
t_objs = [] # 存线程实例
for i in range(50):
t = threading.Thread(target=run, args=("t-%s" % i,))
t.start()
t_objs.append(t)
for t in t_objs: # 循环线程实例列表,等待所有线程执行完毕
t.join()
print("----------all threads has finished...", threading.active_count())
print("num:", num)
RLock 递归锁 说白了就是在一个大锁中还要再包含子锁,以防多把锁时弄混,实际用处少
import threading, time
def run1():
print("grab the first part data")
lock.acquire()
global num
num += 1
lock.release()
return num
def run2():
print("grab the second part data")
lock.acquire()
global num2
num2 += 1
lock.release()
return num2
def run3():
lock.acquire()
res = run1()
print('--------between run1 and run2-----')
res2 = run2()
lock.release()
print(res, res2)
num, num2 = 0, 0
lock = threading.RLock() # 生成RLock锁
for i in range(1):
t = threading.Thread(target=run3)
t.start()
while threading.active_count() != 1:
print(threading.active_count())
else:
print('----all threads done---')
print(num, num2)
6.semaphore 信号量 允许n个线程同时运行,多线程时加快运行速度
import threading, time
def run(n):
semaphore.acquire()
time.sleep(1)
print("run the thread: %s\n" % n)
semaphore.release()
if __name__ == '__main__':
semaphore = threading.BoundedSemaphore(5) # 最多允许5个线程同时运行
for i in range(22):
t = threading.Thread(target=run, args=(i,))
t.start()
while threading.active_count() != 1:
pass # print threading.active_count()
else:
print('----all threads done---')
#print(num)
7.events 处理多个线程间的交互,例如红绿灯,set,clear,wait,is_set
import time
import threading
event = threading.Event() # 生成event对象
def lighter():
count = 0
event.set() # 先设置标志位(绿灯)
while True:
if 5 < count < 10:
event.clear() # 把标志位清空(红灯)
print("\033[41;1mred light is on....\033[0m")
elif count > 10:
event.set() # 重新设置标志位(绿灯)
count = 0
else:
print("\033[42;1mgreen light is on....\033[0m")
time.sleep(1)
count += 1
def car(name):
while True:
if event.is_set(): # 标志位被设置,代表绿灯
print("[%s] running..." % name)
time.sleep(1)
else:
print("[%s] sees red light , waiting...." % name)
event.wait() # 等待event被设置
print("\033[34;1m[%s] green light is on, start going...\033[0m" % name)
light = threading.Thread(target=lighter, ) # 生成一个线程处理红绿灯
light.start()
car1 = threading.Thread(target=car, args=("Tesla",)) # 生成一个线程处理车
car1.start()
8.queue 队列,put,get,qsize
线程queue,只能在当前进程访问
Queue 模块中的常用方法:
Queue.qsize() 返回队列的大小
Queue.empty() 如果队列为空,返回True,反之False
Queue.full() 如果队列满了,返回True,反之False
Queue.full 与 maxsize 大小对应
Queue.get([block[, timeout]])获取队列,timeout等待时间
Queue.get_nowait() 相当Queue.get(False)
Queue.put(item) 写入队列,timeout等待时间
Queue.put_nowait(item) 相当Queue.put(item, False)
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作
# 线程queue,只能在当前进程访问
import queue
# 按优先级排序
q = queue.PriorityQueue()
q.put((-1, "chenronghua"))
q.put((3, "hanyang"))
q.put((10, "alex"))
q.put((6, "wangsen"))
print(q.get())
print(q.get())
print(q.get())
print(q.get())
# # 后入先出
# q = queue.LifoQueue()
#
# q.put(1)
# q.put(2)
# q.put(3)
# print(q.get())
# print(q.get())
# print(q.get())