多线程
一、多线程
1.1、多线程实例
Python中提供了threading模块来对多线程的操作,线程是应用程序中工作的最小单元。
多线程的现实有两种方式:
方法一:将要执行的方法作为参数传给Thread的构造方法(和多进程类似)
t = threading.Thread(target=action, args=(i,))
示例:
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")
方法二:从Thread继承,并重写run()
P = threading.Thread
p.start() → _start_new_thread(self.__bootstrap, ()) → self.__bootstrap_inner() → self.run()
try:
if self.__target:
self.__target(*self.__args, **self.__kwargs)
所以如果重写了run,就直接调用run的函数了,如果run没有重写,就调用target函数。
示例:
import threading
import time
class Hello(threading.Thread):
def __init__(self, args):
super(Hello, self).__init__() #继承父类的构造函数
self.args = args
global a #定义全局变量a
print("a = {0}".format(a))
a += 1
def run(self): #重写run方法,主函数里调用start的时候会默认调用run方法
print("开始子进程 {0}".format(self.args))
print("结束子进程 {0}".format(self.args))
if __name__ == '__main__':
a = 1
print("start main")
t1 = Hello(5)
time.sleep(3)
t2 = Hello(5)
t1.start()
t2.start()
print("#####a = {0}####".format(a))
print("end main")
1.2、线程锁
通过threading.Lock()来创建锁,函数在执行的只有先要获得锁,执行完以后要释放锁:
- with lock: #获得锁,会自动释放锁
- lock.acquire(),lock.release()
示例:
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()
1.3、线程共享变量
多线程和多进程不同之处在于多线程本身就是可以和父进程共享内存的,这也是为什么其中一个线程挂掉以后,其他线程也会死掉的道理。
示例:
import threading
l = list()
l += range(1, 10)
def worker():
l.append("ling")
l.append("shang")
l.append("hello")
if __name__ == "__main__":
t = threading.Thread(target=worker)
t.start()
print(l)
1.4、线程池
通过传入一个参数组来实现多线程,并且它的多线程是有序的,顺序与参数组中的参数顺序保持一致
安装包:
pip install threadpool
调用格式:
from threadpool import *
pool = ThreadPool(poolsize)
requests = makeRequests(some_callable, list_of_args, callback)
[pool.putRequest(req) for req in requests]
pool.wait()
示例:
import threadpool
def hello(m, n, o):
print("m = %s, n = %s, o = %s" % (m, n, o))
if __name__ == '__main__':
# 方法1
lst_vars_1 = ['1', '2', '3']
lst_vars_2 = ['4', '5', '6']
func_var = [(lst_vars_1, None), (lst_vars_2, None)]
# 方法2
dict_vars_1 = {'m': '1', 'n': '2', 'o': '3'}
dict_vars_2 = {'m': '4', 'n': '5', 'o': '6'}
func_var = [(None, dict_vars_1), (None, dict_vars_2)]
pool = threadpool.ThreadPool(2)
requests = threadpool.makeRequests(hello, func_var)
[pool.putRequest(req) for req in requests]
pool.wait()