任务能够由多进程完成,也能够由一个进程内的多线程完成。
咱们前面提到了进程是由若干线程组成的,一个进程至少有一个线程。
因为线程是操做系统直接支持的执行单元,所以,高级语言一般都内置多线程的支持,Python也不例外,而且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。Python的标准库提供了threading模块。html
在python中多线程的实现方法有2种。python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import threading def worker(args): print("开始子进程 {0}".format(args)) print("结束子进程 {0}".format(args)) if __name__ == '__main__': print("start main") t1 = threading.Thread(target=worker, args=(1,)) t2 = threading.Thread(target=worker, args=(2,)) t1.start() t2.start() print("end main") |
输出结果多线程
1 2 3 4 5 6 |
start main 开始子进程 1 结束子进程 1 开始子进程 2 结束子进程 2 end main |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import threading import time class Hello(threading.Thread): def __init__(self, args): super(Hello, self).__init__() #注意:要显式的调用父类的初始化函数 self.args = args def run(self): print("开始子进程 {0}".format(self.args)) time.sleep(1) print("结束子进程 {0}".format(self.args)) if __name__ == '__main__': a = 1 print("start main") t1 = Hello(1) t2 = Hello(2) t1.start() t2.start() print("end main") |
输出结果并发
1 2 3 4 5 6 |
start main 开始子进程 1 开始子进程 2 end main 结束子进程 1 结束子进程 2 |
enumerate()
列表长度相等。thread identifier
。这是个非零的整数。该值无特殊含义。current_thread()
建立的虚拟线程对象,不包括已结束和还没开始的线程。RuntimeError
错误。RuntimeError
错误。假如主线程不是守护线程,该主线程建立的全部子线程该值为False。 threading.Lock()
进行,操做相似于多进程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import threading import time def worker(name, lock): with lock: print("start {0}".format(name)) time.sleep(5) print("end {0}".format(name)) if __name__ == "__main__": lock = threading.Lock() t1 = threading.Thread(target=worker, args=("worker1", lock)) t2 = threading.Thread(target=worker, args=("worker2", lock)) t1.start() t2.start() |
输出结果app
1 2 3 4 |
start worker1 end worker1 start worker2 end worker2 |
固然,获取锁也能够经过lock.acquire()
完成,释放锁经过lock.release()
完成。ide
1 2 3 4 5 6 7 8 |
def worker(name, lock): lock.acquire() try: print("start {0}".format(name)) time.sleep(5) print("end {0}".format(name)) finally: lock.release() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import threading l = list() l += range(1, 4) def worker(): l.append("GOD") if __name__ == "__main__": t1 = threading.Thread(target=worker) t2 = threading.Thread(target=worker) t1.start() t2.start() print(l) |
输出结果函数
1 |
[1, 2, 3, 'GOD', 'GOD'] |
在使用多线程处理任务时也不是线程越多越好,因为在切换线程的时候,须要切换上下文环境,依然会形成cpu的大量开销。为解决这个问题,线程池的概念被提出来了。预先建立好一个较为优化的数量的线程,让过来的任务马上可以使用,就造成了线程池。
此处介绍threapool
是一个第三方模块,须要使用pip install threadpool
安装。优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import threadpool def hello(m, n, o): print("m = {0} n={1} o={2}".format(m, n, o)) if __name__ == '__main__': lst_vars_1 = ['1', '2', '3'] lst_vars_2 = ['4', '5', '6'] func_var = [(lst_vars_1, None), (lst_vars_2, None)] pool = threadpool.ThreadPool(2) requests = threadpool.makeRequests(hello, func_var) [pool.putRequest(req) for req in requests] pool.wait() |
输出结果ui
1 2 |
m = 1 n=2 o=3 m = 4 n=5 o=6 |
Executor Objects
,更多内容点击concurrent.futures — Launching parallel tasks查看官方介绍。threading
的内容能够点击threading — Thread-based parallelism查看官方介绍。