Python高级语法——多线程——学习心得笔记

Python高级语法——多线程——学习心得笔记

参考博客:

1. 多线程 VS 多进程

  • 程序:一堆代码以文本形式存入一个文档

  • 进程:程序运行的一个状态

    • 包含地址空间,内存,数据栈
    • 每个进程有自己独立的运行环境
    • 多进程共享数据是一个问题
  • 线程

    • 一个线程的独立运行片段,一个进程可以有多个线程
    • 轻量化的进程
    • 一个进程的多个线程共享数据和山下文运行环境
    • 共享互斥问题
  • 全局解释器(GIL)

    • Python代码的执行是由python虚拟机进行控制
    • 在主循环中只能有一个控制的线程在执行
  • Python包

    • threading 通用的包
    • 查看案例28_1单线程耗时长
    • 查看案例28_4 多线程耗时短
    • 多线程,传递参数案例28_5
      28-1
# 多线程实例
# 先写一个单线程

import time

# 单线程实例

def loop1():
    # ctime得到当前的时间
    print("Start loop 1 at: ", time.ctime())
    # 睡眠一定时间,单位是秒
    time.sleep(2)
    print("End loop 1 at: ", time.ctime())

def loop2():
    # ctime得到当前的时间
    print("Start loop 2 at: ", time.ctime())
    # 睡眠一定时间,单位是秒
    time.sleep(3)
    print("End loop 2 at: ", time.ctime())

def main():
    print("Starting at: ", time.ctime())
    loop1()
    loop2()
    print("All done at: ", time.ctime())

if __name__ == '__main__':
    main()

28_4

# 多线程实例
# 28_1.py单线程改写为多线程
# 多线程2,查看结果
# 主程序执行完毕添加一个睡眠时间,等待loop1和loop2执行完

import time
import _thread as thread

# 单线程实例

def loop1():
    # ctime得到当前的时间
    print("Start loop 1 at: ", time.ctime())
    # 睡眠一定时间,单位是秒
    time.sleep(2)
    print("End loop 1 at: ", time.ctime())

def loop2():
    # ctime得到当前的时间
    print("Start loop 2 at: ", time.ctime())
    # 睡眠一定时间,单位是秒
    time.sleep(3)
    print("End loop 2 at: ", time.ctime())

def main():
    print("Starting at: ", time.ctime())
    # 启动一个多线程,()中是放前面函数的参数的
    thread.start_new_thread(loop1, ())
    # 再启动一个多线程
    thread.start_new_thread(loop2, ())
    print("All done at: ", time.ctime())



if __name__ == '__main__':
    main()
    while True:
        time.sleep(1)

28_5

# 多线程实例
# 多线程传递参数

import time
import _thread as thread

# 单线程实例

def loop1(in1):
    # ctime得到当前的时间
    print("Start loop 1 at: ", time.ctime())
    print("我是参数", in1)
    # 睡眠一定时间,单位是秒
    time.sleep(2)
    print("End loop 1 at: ", time.ctime())

def loop2(in1, in2):
    # ctime得到当前的时间
    print("Start loop 2 at: ", time.ctime())
    print("我是参数", in1, "和参数", in2)
    # 睡眠一定时间,单位是秒
    time.sleep(3)
    print("End loop 2 at: ", time.ctime())

def main():
    print("Starting at: ", time.ctime())
    # 启动一个多线程,()中是放前面函数的参数的
    # 只有一个参数,后面的逗号要写上,才代表一个元组touple
    thread.start_new_thread(loop1, ("Felix", ))
    # 再启动一个多线程
    thread.start_new_thread(loop2, ("Fang", "Bai"))
    time.sleep(6)
    print("All done at: ", time.ctime())

if __name__ == '__main__':
    main()
  • threading的使用
    • 直接利用threading.Thread生成Thread实例
      1. t = threading.Thread(target=xxx, args=(xxx,))
      2. t.start(): 启动多线程
      3. t.join(): 等待多线程执行完毕
      • 看案例28_6
        28-6
# 多线程实例
# 多线程传递参数
# 包threading

import time
import threading

# 单线程实例

def loop1(in1):
    # ctime得到当前的时间
    print("Start loop 1 at: ", time.ctime())
    print("我是参数", in1)
    # 睡眠一定时间,单位是秒
    time.sleep(2)
    print("End loop 1 at: ", time.ctime())

def loop2(in1, in2):
    # ctime得到当前的时间
    print("Start loop 2 at: ", time.ctime())
    print("我是参数", in1, "和参数", in2)
    # 睡眠一定时间,单位是秒
    time.sleep(3)
    print("End loop 2 at: ", time.ctime())

def main():
    print("Starting at: ", time.ctime())
    # 生成threading.Thread()实例
    t1 = threading.Thread(target=loop1, args=("Felix",))
    t1.start()
    t2 = threading.Thread(target=loop2, args=("Fang", "Bai"))
    t2.start()
    # time.sleep(6)知道上面的程序时间,手动添加等待时间
    # 等待多线程执行完毕,在执行之后的代码,替代上面的功能
    t1.join()
    t2.join()
    print("All done at: ", time.ctime())



if __name__ == '__main__':
    main()

- 守护线程-setDaemon
    - 如果在程序中子线程设置成守护线程
    - 则子线程在主线程结束时也会自动退出
    - 一般认为,守护线程不重要或者不允许离开主线程独立运行
    - 守护线程案例能否有效运行跟环境有关
  • 线程常用属性

    • threading.currentThread: 返回当前的线程变量

    • threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。

    • threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

    • 除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:

      run(): 用以表示线程活动的方法。
      start():启动线程活动。
      join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
      isAlive(): 返回线程是否活动的。
      getName(): 返回线程名。
      setName(): 设置线程名。

  • 直接继承threading.Thread

    • 直接继承Thread
    • 重写run函数
    • 类实例可以直接运行

2. 共享变量

  • 当多个线程同时访问一个变量的时候,会产生共享变量的问题

  • 解决变量冲突问题

    • 锁,信号灯
    • 是一个标志,表示一个线程在占用一些资源
    • 使用方法
      • 上锁
      • 使用共享资源,放心的使用
      • 取消锁,释放锁
  • 线程安全问题

    • 如果一个资源或者变量,它对于多线程来讲,不用枷锁也不会引起任何问题,则为线程安全
    • 线程不安全的变量类型:list, set, dict
    • 线程安全变量类型: queue
  • 生产消费者问题

    • 一个模,可以用来搭建消息队列
    • queue是一个用来存放变量的数据结构,特点是先进先出
    • 内部元素需要排队,可以理解成一个特殊的list
  • 死锁问题

3. 线程替代方案

  • subprocess
    • 完全跳过线程,使用进程
    • 是派生进程的主要替代方案
  • multiprocessing
    • 使用threading接口派生
    • 允许多核或者多cpu派生进程,接口跟threading相似
  • concurrent.futures
    • 新的异步执行模块
    • 任务级别的操作

4. 多进程

  • 类似QQ多开

  • 完全独立的进程

  • 主要问题:进程间通讯(InterprocessCommuication, IPC)

  • 进程之前无任何共享状态

  • 进程的创建

  • 派生子类

  • 在os中查看pid ppid以及他们的关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值