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())
posted @ 2020-07-04 19:27  Jerome12138  阅读(164)  评论(0编辑  收藏  举报