python多线程下有一个GIL全局锁,执行线程代码前,必须先拿到GIL锁,每执行100条字节码释放一次GIL锁,所以,Python多线程并不是真正多线程,只有通过其他语言来扩展,或者使用多进程替代,但是进程开销大
thread 模块 是较底层的线程实现,没找到thread.py,应该是C实现的
threading模块提供了很多方法、类,方便调用,threading和multithprocessing是python实现的,方法几乎相同,具体参考源码或手册
一、线程
线程模块: thread 和 threading
1.1 创建线程有两种方法:直接调用线程函数 和 创建线程封装类
#1.直接创建线程并执行,不接受命名参数传递
thread.start_new_thread(function,*args,**kwargs=None);
#2.通过 threading.Thread创建线程,命名参数传递,
th = threading.Thread(group=None, target=None, name=None,args=(), kwargs=None, verbose=None))
th.start();
#3.继承threading.Thread创建 线程类,重写run(self)实现线程功能逻辑,
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__();
#必须调用threading.Thread.__init__()初始化线程
def run(self):
th = MyThread();
th.start(); #调用start()启动线程,th.join()等待th线程结束
二、进程:
多进程模块multiprocessing,方法和多线程差不多
要在 if __name__ == “__main__”下才能使用?
进程的属性:
autokey验证、exitcode、name、pid、daemon(start之前设置,父进程结束时结束)
进程的方法:
is_alive()、join(timeout=0永久)、run()、start()、terminate()强制终止
2.1创建进程的2种方式:
#进程一定要指定名称传入参数,因为Process构造函数的第一个是group
#进程必须要.start()
p = Process(target = runFun, args=(,) ).start();
#2.创建自己的进程封装类,当调用 start()时,自动调用run方法
class MyPrecess(multiprocessing.Process):
def __init__(self);
multiprocessing.Process.__init__(self)
def run(self):
pass;
2.2 进程池:
p = Pool(processes = n) #进程池,n默认大小是cpu数量,
p.apply_async(func,args) #非阻塞提交,提交后就继续向下执行
p.apply(func,args) #阻塞提交,若pool中没有可用进程,则阻塞等待
p.close() #等待已提交进程执行完,然后关闭
p.join() #等待所有进程执行完,先close再Join
三、同步与通信:锁、信号量、管道等
#1. Lock:临界区、
lock = thread.allocate_lock(); #创建锁
lock = threading.RLock();
#线程推荐使用threading,
#multiprocessing有的方法和类,threading基本都有,
#所以,后续只写出multiprocessing,但其实是通用的
lock = multiprocessing.Lock(); #创建锁
lock = multiprocessing.RLock();
lock.acquire(); #获得锁
lock.release(); #释放锁
#2.Semaphore:用来控制对共享资源的访问数量
#BoundedSemaphore
s = multiprocessing.Semaphore(n=1) #创建n个资源
s.acquire() #获取资源
s.release() #释放资源
#3.Condition:进程在条件对象上等待被唤醒
con = Condition(lock=None);
con.wait(timeout=None);
con.notify();
con.notifyAll();
#4.Event: 进程等待某个事件被set,和wait/notify类似
e = multiprocessing.Event()
e.wait(timeout=None) #进程在event上等待被set
e.set() #设置event,等待的进程被唤醒
e.clear()
#5. Queue:多进程安全的队列
q = multiprocessing.Queue()
q.put(obj, block=True, timeout=None)
q.get(blocked=True,timeout=None)
#6.管道Pipe
#duplex=true,全双工模式,pipe[0]、pipe[1]都可收发消息,默认false,
p = multiprocessing.Pipe(duplex=false);
pipe[0].send(data); #pipe[0]只能发送消息
pipe[1].recv() #Pipe[1]只能收消息
四、Timer
#每隔 interval 时间就调用一次function,threading模块
threading.Thread.Timer(interval, function, args=[], kwargs={}))
#调用。。。
threading._Timer(interval, function, args=[], kwargs={}))
timer.start(); #调用run()方法,而run方法又调用function
timer.cancel();