Python多线程指南
发布时间:2021-12-10 14:51:43 所属栏目:语言 来源:互联网
导读:线程概念: ASP站长网 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,
线程概念: ASP站长网线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。线程可以分为两类: 内核线程:由操作系统内核创建和撤销。 用户线程:不需要内核支持而在用户程序中实现的线程。 全局解释性锁(GIL): 在讲Python多线程,有一个绕不开的东西,叫全局解释性锁(Global Interpreter Lock)。这东西导致了无论你启多少个线程,你有多少个cpu, Python在执行的时候同一时刻只允许一个线程运行。这就导致了大家对Python多线程的印象普遍就是‘鸡肋“。 需要注意的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL。 线程模块: Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。_thread 提供了低级别的、原始的线程以及一个简单的锁,它相比于 threading 模块的功能还是比较有限的。threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法: threading.currentThread(): 返回当前的线程变量。 threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。 除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法: run(): 用以表示线程活动的方法。 start():启动线程活动。 join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。 isAlive(): 返回线程是否活动的。 getName(): 返回线程名。 setName(): 设置线程名。 Python threading模块: (1)线程创建方式一:直接调用线程,创建Thread类,并传递一个需要多线程运行的函数。示例如下: import threading import time def func(no): time.sleep(2) print("the thread number:%s"%no) time_start = time.time() thread_list = [] for i in range(10): t = threading.Thread(target=func,args=(i,)) #生成线程实例 t.start() #启动线程 thread_list.append(t) for t in thread_list: t.join() #等待线程中止 time_end = time.time() print("程序总共运行%d秒"%int(time_end-time_start)) #运行结果: the thread number:4 the thread number:2 the thread number:5 the thread number:1 the thread number:3 the thread number:0 the thread number:7 the thread number:9 the thread number:6 the thread number:8 程序总共运行2秒 (2)线程创建方式二:继承式调用,创建一个Thread类的子类,并重写Thread类的run方法。示例如下: import threading import time class TestThread(threading.Thread): def __init__(self,no): threading.Thread.__init__(self) self.no = no def run(self): #重写父类Thread的run方法,改方法内定义每个线程要运行的程序代码 time.sleep(2) print("the thread number:%s" % self.no) for i in range(10): t = TestThread(i) t.start() (3)守护进程: import threading import time def run(i): print("run({}) start".format(i)) time.sleep(2) print("run({}) end".format(i)) def main(): for i in range(5): t = threading.Thread(target=run,args=(i,)) t.start() m = threading.Thread(target=main,args=()) m.setDaemon(False) m.start() m.join(timeout=1) print("main thread end") # m.setDaemon(True) 运行结果: run(0) start run(1) start run(2) start run(3) start run(4) start main thread end # m.setDaemon(False) 运行结果: run(0) start run(1) start run(2) start run(3) start run(4) start main thread end run(3) end run(2) end run(0) end run(4) end run(1) end 从上述示例中可以看出:将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务 (编辑:焦作站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |