#进程与线程的关系
"""
多进程(主进程,子进程):
优点:能同时利用多个CPU,进行多个操作,提高效率。
缺点:耗费内存资源(进程要开辟内存空间),进程不是越多越好,CPU个数 = 进程个数。
注意:进程创建内存空间,线程共享内存空间,进程里有全局解释器锁,进程中一次只应许一个线程被处理。
使用场景:计算密集型适合多进程。
多线程(主线程,子线程):
优点:共享内存,IO操作时(不用CPU),创造并发操作(多个操作同时进行),提高效率。
缺点:抢占资源,请求上下文切换非常耗时(线程处理切换后找到上次处理的地方),线程不是越多越好,视具体案例而定。
注意:在计算机中,执行任务的最小单元就是线程。
使用场景:IO密集型适合多线程。
"""
"""
队列queue
先进先出,一边放,另一边取
可设置最大个数,get等待,get_nowait不等待
"""
"""
使用线程
1、创建线程
import threading
import time
def f1():
pass
def f2(a1, a2):
time.sleep(10)
pass
t = threading.Thread(target=f1, args=(11,22,33))
t.start() # 线程开始跑,创建的是子线程
2、线程锁
防止出现脏数据,一个线程读取数据并对其加锁,CPU切换线程后其他线程不能读取数据,
3、线程池
Python内部没有提供线程池,需要自定义
"""
import threading
import time def f1():
pass def f2(a1, a2):
time.sleep(10)
pass t1 = threading.Thread(target=f2, args=(11, 22))
t1.setDaemon(True) # 主线程是否等待子线程
t1.start() # 线程开始跑,创建的是子线程
print("第一次等待中")
t1.join(2) # 主线程等待子线程多久,不加参数无限等待
t2 = threading.Thread(target=f2, args=(11, 22))
t2.setDaemon(True)
t2.start() # 线程开始跑,创建的是子线程
print("第二次等待中")
t2.join(2) # 主线程等待子线程的执行的最多等待时间,超过时间,主线程继续执行下一部分
t3 = threading.Thread(target=f2, args=(11, 22))
t3.setDaemon(True) # 主线程执行完(解释器执行代码),是否等待子线程执行完再关闭,True:不等待:False:等待。默认为False
t3.start() # 线程开始跑,创建的是子线程

  线程event

#!/usr/bin/env python
# -*- coding;utf-8 -*-
"""
线程event
"""
import threading
import time def do(event):
print("线程前半部分")
event.wait() # 阻塞(十字路口),红灯则等待,绿灯则继续执行
print("线程后半部分") event_obj = threading.Event() for i in range(10):
t = threading.Thread(target=do, args=(event_obj,))
t.start()
# 耗时十分钟
# time.sleep(10) event_obj.clear() # 让灯变红
inp = input("请输入内容:>>>")
if inp == "true":
event_obj.set() # 让灯变绿,线程就都可以继续执行

  线程数据共享

#!/usr/bin/env python
# -*- coding;utf-8 -*-
"""
默认情况下线程数据不共享
线程与线程之间数据可以共享
"""
from threading import Thread
li = [] def foo(i):
li.append(i)
print("hello", li) if __name__ == "__main__":
for i in range(10):
t = Thread(target=foo, args=(i,))
t.start()

  线程池

  1. 简单线程池

    #!/usr/bin/env python
    # -*- coding;utf-8 -*-
    """
    自定义线程池博客园教程地址
    http://www.cnblogs.com/wupeiqi/articles/4839959.html
    """
    import queue
    import threading
    import time class ThreadPool(object): def __init__(self, max_num=20):
    self.queue = queue.Queue(max_num)
    for i in range(max_num):
    self.queue.put(threading.Thread) def get_thread(self):
    return self.queue.get() def add_thread(self):
    self.queue.put(threading.Thread) def func(i, arg):
    print(i)
    time.sleep(4)
    # 在队列中增加线程类
    arg.add_thread() if __name__ == "__main__":
    # 在队列中创建线程类
    pool = ThreadPool(10)
    for i in range(30):
    # 获得类
    thread = pool.get_thread()
    # 对象 = 类()
    ret = thread(target=func, args=(i, pool))
    ret.start()
  2. 高级线程池
    #!/usr/bin/env python
    # -*- coding;utf-8 -*-
    import threading
    import time
    import queue
    import contextlib
    StopEvent = object() class Threadpool(object): def __init__(self, max_num):
    self.max_num = max_num
    # 创建任务队列
    self.queue = queue.Queue()
    self.terminal = False
    # 表示真实创建的线程列表
    self.generate_list = []
    # 表示空闲的线程列表
    self.free_list = [] def run(self, func, args, callback=None):
    """
    线程池执行一个任务
    :param func: 执行任务的函数
    :param args: 任务函数的参数(以元组形式存在的任务包,封装了几个参数)
    :param callback: 任务执行失败或者成功后执行的回调函数,回调函数有两个参数
    :return:
    """
    # 往任务队列里加任务
    w = (func, args, callback)
    self.queue.put(w)
    # 如果空闲线程等于零并且真实创建的线程数小于任务数
    if len(self.free_list) == 0 and len(self.generate_list) < self.max_num:
    self.generate_thread() def generate_thread(self):
    """
    创建一个线程
    :return:
    """
    t = threading.Thread(target=self.call)
    t.start() def call(self):
    """
    循环去获取任务函数并执行任务函数
    :return:
    """
    current_thread = threading.current_thread()
    self.generate_list.append(current_thread)
    # 去任务并执行
    event = self.queue.get()
    while event != StopEvent:
    # 如果是元组任务,解开任务包,执行任务
    func, args, callback = event try:
    ret = func(*args)
    success = True
    except Exception as e:
    success = False
    ret = e if callback is not None:
    try:
    callback(success, ret)
    except Exception as e:
    pass
    with self.work_station(self.free_list, current_thread):
    if self.terminal:
    event = StopEvent
    else:
    event = self.queue.get() else:
    self.generate_list.remove(current_thread) def close(self):
    # 中途终止线程
    num = len(self.generate_list)
    while num:
    self.queue.put(StopEvent)
    num -= 1 def terminate(self):
    # 终止线程(不清空队列),线程一直在等待拿,程序不会退出
    """
    终止线程(清空队列)
    while self.generate_list:
    self.queue.put(StopEvent)
    """
    self.terminate = True
    max_num = len(self.generate_list)
    # self.queue.empty()
    while max_num:
    max_num = len(self.generate_list)
    max_num -= 1
    #self.queue.empty() @contextlib.contextmanager
    def work_station(self, station, val):
    station.append(val)
    try:
    yield
    finally:
    station.remove(val) def work(i):
    # time.sleep(3)
    print(i) pool = Threadpool(10)
    for i in range(50):
    pool.run(func=work, args=(i,), callback=None) # pool.terminate()
    pool.close()
  3. 绝版线程池
    #!/usr/bin/env python
    # -*- coding;utf-8 -*-
    """
    自定义线程池博客园教程地址
    http://www.cnblogs.com/wupeiqi/articles/4839959.html
    """
    import queue
    import threading
    import contextlib
    import time
    StopEvent = object() class ThreadPool(object): def __init__(self, max_num, max_task_num = None):
    if max_task_num:
    self.q = queue.Queue(max_task_num)
    else:
    self.q = queue.Queue()
    self.max_num = max_num
    self.cancel = False
    self.terminal = False
    self.generate_list = []
    self.free_list = [] def run(self, func, args, callback=None):
    """
    线程池执行一个任务
    :param func: 任务函数
    :param args: 任务函数所需参数
    :param callback: 任务执行失败或成功后执行的回调函数,回调函数有两个参数1、任务函数执行状态;2、任务函数返回值(默认为None,即:不执行回调函数)
    :return: 如果线程池已经终止,则返回True否则None
    """
    if self.cancel:
    return
    if len(self.free_list) == 0 and len(self.generate_list) < self.max_num:
    self.generate_thread()
    w = (func, args, callback,)
    self.q.put(w) def generate_thread(self):
    """
    创建一个线程
    """
    t = threading.Thread(target=self.call)
    t.start() def call(self):
    """
    循环去获取任务函数并执行任务函数
    """
    current_thread = threading.currentThread()
    self.generate_list.append(current_thread) event = self.q.get()
    while event != StopEvent: func, arguments, callback = event
    try:
    result = func(*arguments)
    success = True
    except Exception as e:
    success = False
    result = None if callback is not None:
    try:
    callback(success, result)
    except Exception as e:
    pass with self.worker_state(self.free_list, current_thread):
    if self.terminal:
    event = StopEvent
    else:
    event = self.q.get()
    else: self.generate_list.remove(current_thread) def close(self):
    """
    执行完所有的任务后,所有线程停止
    """
    self.cancel = True
    full_size = len(self.generate_list)
    while full_size:
    self.q.put(StopEvent)
    full_size -= 1 def terminate(self):
    """
    无论是否还有任务,终止线程
    """
    self.terminal = True while self.generate_list:
    self.q.put(StopEvent) self.q.queue.clear() @contextlib.contextmanager
    def worker_state(self, state_list, worker_thread):
    """
    用于记录线程中正在等待的线程数
    """
    state_list.append(worker_thread)
    try:
    yield
    finally:
    state_list.remove(worker_thread) # How to use
    pool = ThreadPool(5) def callback(status, result):
    # status, execute action status
    # result, execute action return value
    pass def action(i):
    print(i) if __name__ == "__main__":
    for i in range(30):
    ret = pool.run(action, (i,), callback)
    time.sleep(0.01) # 等待的时间xiao'l
    print(len(pool.generate_list), len(pool.free_list))
    print(len(pool.generate_list), len(pool.free_list))
    pool.close() # 子线程结束时,主线程就结束,time.sleep后的内容可能没有结果
    # pool.terminate()

      

Python全栈开发:线程代码实例的更多相关文章

  1. Python全栈开发 线程和进程

    一.线程 线程是程序工作的最小单元,由进程生成,生成的线程间会共享内存空间.Python中创建线程比较简单,导入threading模块,创建线程实例.下面这段代码是一个简单的多线程例子 import ...

  2. python全栈开发 * 线程锁 Thread 模块 其他 * 180730

    一,线程Thread模块1.效率更高(相对于进程) import time from multiprocessing import Process from threading import Thre ...

  3. python全栈开发 * 线程队列 线程池 协程 * 180731

    一.线程队列 队列:1.Queue 先进先出 自带锁 数据安全 from queue import Queue from multiprocessing import Queue (IPC队列)2.L ...

  4. Python全栈开发:递归实例

    #!/usr/bin/env python # -*- coding;utf-8 -*- """ 递归不能无限,python会限制递归深度,递归主要用于费布拉切数列 &q ...

  5. Python全栈开发【模块】

    Python全栈开发[模块] 本节内容: 模块介绍 time random os sys json & picle shelve XML hashlib ConfigParser loggin ...

  6. Python全栈开发【面向对象】

    Python全栈开发[面向对象] 本节内容: 三大编程范式 面向对象设计与面向对象编程 类和对象 静态属性.类方法.静态方法 类组合 继承 多态 封装 三大编程范式 三大编程范式: 1.面向过程编程 ...

  7. Python全栈开发【基础三】

    Python全栈开发[基础三]  本节内容: 函数(全局与局部变量) 递归 内置函数 函数 一.定义和使用 函数最重要的是减少代码的重用性和增强代码可读性 def 函数名(参数): ... 函数体 . ...

  8. python全栈开发中级班全程笔记(第二模块、第四章)(常用模块导入)

    python全栈开发笔记第二模块 第四章 :常用模块(第二部分)     一.os 模块的 详解 1.os.getcwd()    :得到当前工作目录,即当前python解释器所在目录路径 impor ...

  9. 学习笔记之Python全栈开发/人工智能公开课_腾讯课堂

    Python全栈开发/人工智能公开课_腾讯课堂 https://ke.qq.com/course/190378 https://github.com/haoran119/ke.qq.com.pytho ...

  10. Python全栈开发【面向对象进阶】

    Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...

随机推荐

  1. mysql中的Date日期格式的问题:只有日期没有时间及格式化时间

    只有日期没有时间,把xml中的date改为timestamp 格式化最简单的方法:@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", time ...

  2. Apache Shiro RememberMe 1.2.4 反序列化漏洞

    拉取镜像 docker pull medicean/vulapps:s_shiro_1 启动环境 docker run -d -p 80:8080 medicean/vulapps:s_shiro_1 ...

  3. !!!myeclipse 上加载本地图片问题,无法加载问题

    出现无法加载本地图片的问题, 原因就是把图片放到了本地项目中的image了,但是myeclipse上没有刷新 这样以后 本地的图片比在线的要快 低级错误,诶!

  4. 6-MySQL高级-索引

    索引 1. 思考 在图书馆中是如何找到一本书的? 一般的应用系统对比数据库的读写比例在10:1左右(即有10次查询操作时有1次写的操作), 而且插入操作和更新操作很少出现性能问题, 遇到最多.最容易出 ...

  5. 【POJ】1251 Jungle Roads

    题目链接:http://poj.org/problem?id=1251 题意:n个村庄字母标号,每个字母后跟m个字母,表示该字母到mi的距离.求构建所有村庄道路的最短距离. 题解:最小生成树裸题.注意 ...

  6. Read-Write lock 看可以,不过看的时候不能写

    当线程“读取”实例的状态时,实例的状态不会改变,只有线程对实例“写入”操作时才会改变.read-write lock 模式将读取和写入分开来处理,在读取数据前获取读锁定,而写入之前,必须获取写锁定. ...

  7. 502Bad Gateway

    502 bad gateway,错误的网关的原因 连接超时,我们向服务器发送请求,由于服务器当前链接太多,导致服务器方面无法给予正常的响应,产生此报错,最好去服务器上找原因. 性能测试常见,可能是由于 ...

  8. 【hihocoder】Demo Day

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 You work as an intern at a robotics startup. Today is your co ...

  9. Web安全之Web 安全介绍与基础入门知识

    web安全介绍与基础入门知识 安全与安全圈 甲方与乙方 甲方:如腾讯,阿里等需要安全服务的公司 乙方:提供安全服务产品的服务型安全公司 web与二进制 web,研究web安全 二进制,研究如客户端安全 ...

  10. 关于soapui如何做安全测试

    1.首先安装soapui5.1.2 第一步:运行SoapUI-Pro-x32-5.1.2_576024.exe文件,按照步骤安装成功: 第二步:拷贝Protection-4.6.jar到soapui安 ...