什么是线程?
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务
Python3中实现多线程有两种方式
1.直接实例化threading.Thread线程对象,实现多线程

import threading import time def print_age(who, age): """ 需要用多线程调用的函数 :param who: :param age: :return: """ print("Hello,every one!") time.sleep(1) print("%s is %s years old !" % (who, age)) if __name__ == "__main__": t1 = threading.Thread(target=print_age, args=("jet", 18, )) # 创建线程1 t2 = threading.Thread(target=print_age, args=("jack", 25, )) # 创建线程2 t3 = threading.Thread(target=print_age, args=("jack", 25,)) # 创建线程3 t1.start() # 运行线程1 t2.start() # 运行线程2 t3.start() # 运行线程3 print("over...")
2.通过继承threading.Thread,并重写run()方法,来实现多线程

import threading import time class MyThread(threading.Thread): """ 使用继承的方式实现多线程 """ def __init__(self, who): super().__init__() # 必须调用父类的构造方法 self.name = who def run(self): print("%s is run..." % self.name) time.sleep(3) if __name__ == "__main__": t1 = MyThread("Jet") # 创建线程1 t2 = MyThread("Jack") # 创建线程2 t1.start() # 运行线程1 t2.start() # 运行线程2 print("over...")
守护线程
可以通过setDaemon()方法将线程设置为守护线程,当守护线程退出时,由它启动的其它子线程将同时退出,不管是否执行完成

import threading import time def print_age(who, age): print("Hello,every one!") time.sleep(1) print("%s is %s years old !" % (who, age)) def daemon_func(): for i in range(18, 25): t = threading.Thread(target=print_age, args=("Jet", i,)) # 创建线程 t.start() if __name__ == "__main__": dt = threading.Thread(target=daemon_func) # 创建线程 dt.setDaemon(True) # 设置为守护线程 dt.start() dt.join(timeout=2) print("over...")
线程锁
因为多线程是共享父进程里面的数据的,所以当多个线程同时修改一份数据的时候,就容易出错,因此就有了锁,锁能确保在同一时间只有一个线程修改这份数据
CPython的GIL(Global Interpreter Lock)是全局线程锁,是确保只有一个线程运行的,与这个锁没有关系,锁的层级不一样,GIL更为底层

# -*- coding: utf-8 -*- import threading import time def add_one(): global num print("Value: %s" % num) time.sleep(1) lock.acquire() # 加锁 num += 1 # 修改数据 lock.release() # 释放锁 if __name__ == "__main__": num = 0 lock = threading.RLock() # 一般都用RLock递归锁 thread_list = [] for i in range(100): t = threading.Thread(target=add_one) t.start() thread_list.append(t) for i in thread_list: i.join() print("Num = %s" % num)
信号量
信号量semaphore,是一个变量,控制着对公共资源或者临界区的访问。信号量维护着一个计数器,指定可同时访问资源或者进入临界区的线程数。用来控制最大线程数的

# -*- coding: utf-8 -*- import threading import time def add_one(): global num semaphore.acquire() # 加锁,最多有五个线程做以下操作 time.sleep(1) num -= 1 print("Value: %s" % num) semaphore.release() # 释放锁 if __name__ == "__main__": num = 100 thread_list = [] semaphore = threading.BoundedSemaphore(5) for i in range(100): t = threading.Thread(target=add_one) t.start() thread_list.append(t) for i in thread_list: i.join() # 等待线程结束 print("Num = %s" % num)
参考资料
http://python.usyiyi.cn/translate/python_352/library/threading.html