进程 vs 线程

  • 进程: 程序运行的一个状态
    • 包含地址空间,内存,数据栈等
    • 每个进程由自己完全独立的运行环境,多进程共享数据是一个问题
  • 线程
    • 一个进程的独立运行片段,一个进程可以由多个线程组成
    • 轻量化的进程,主从关系
    • 一个进程的多个现成间共享数据和上下文运行环境
    • 共享互斥问题
  • 全局解释器锁(GIL)
    • Python代码的执行是由python虚拟机进行控制
    • 在主循环中只能更有一个控制线程在执行
  • 参考资料
  • https://www.cnblogs.com/jokerbj/p/7460260.html
  • http://www.dabeaz.com/python/UnderstandingGIL.pdf

多线程

  • 为了提高cpu等速度快的资源的使用率,加快程序相应速度
  • python目前常用的包为 threading - threading的使用 - 直接利用threading.Thread生成Thread实例 1. t = threading.Thread(target=xxx, args=(xxx,)) 2. t.start():启动多线程 3. t.join(): 等待多线程执行完成 4. 案例04 5. 案例05: 加入join后比较跟案例04的结果的异同
#利用time延时函数,生成两个函数
# 利用多线程调用
# 计算总运行时间
# 练习带参数的多线程启动方法
import time
# 导入多线程处理包
import threading

def loop1(in1):
    print('Start loop 1 at :', time.ctime())
    print("我是参数 ",in1)
    time.sleep(4)
    print('End loop 1 at:', time.ctime())

def loop2(in1, in2):
    print('Start loop 2 at :', time.ctime())
    print("我是参数 " ,in1 , "和参数  ", in2)
    time.sleep(2)
    print('End loop 2 at:', time.ctime())

def main():
    print("Starting main at:", time.ctime())
    # 生成threading.Thread实例
    t1 = threading.Thread(target=loop1, args=("王老大",))
    t1.start()

    t2 = threading.Thread(target=loop2, args=("王大鹏", "王小鹏"))
    t2.start()
    
    t1.join()
    t2.join()
    #等待线程执行完成,才执行下一个
    print("All done at:", time.ctime())

if __name__ == "__main__":
    main()
    # 一定要有while语句
    # 因为启动多线程后本程序就作为主线程存在
    # 如果主线程执行完毕,则子线程可能也需要终止
  #  while True:
  #      time.sleep(10)	
  • 守护线程-daemon
    • 如果在程序中将子线程设置成守护线程,则子线程会在主线程结束的时候自动退出
    • 设置依据:守护线程不重要或者不允许离开主线程独立运行
    • 使用:线程实例名.setDaemon(true)---t1.setDaemon(True),或t1.daemon = True,要求在启动前设置
    • 守护线程案例能否有效果跟环境相关
  • 案例:
import time
import threading

def fun():
   print("Start fun")
   time.sleep(2)
   print("end fun")

print("Main thread")

t1 = threading.Thread(target=fun, args=() )
# 设置守护线程的方法,必须在start之前设置,否则无效
t1.setDaemon(True)
#t1.daemon = True
t1.start()

time.sleep(1)
print("Main thread end")
  • 线程常用属性

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

  • threading.enumerate:返回一个包含正在运行的线程的list,正在运行的线程指的是线程启动后,结束前的状态

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

  • thr.setName: 给线程设置名字

  • thr.getName: 得到线程的名字

  • 直接继承自threading.Thread

    • 直接继承Thread
    • 重写run函数
    • 类实例可以直接运行
    • 案例09
    • 案例10, 工业风案例