Python学习笔记-17.10.11
Python线程
基本概念:
线程:进程中的每个子任务,不能独立存在
进程:独立的所有子任务的集合
线程,进程:目的都是想同时完成任务
特点:
进程的特点:独立(内存独立,cpu使用独立)启动进程开销大(速率低),进程之间很难共享数据,和数据通信,数据安全高。
线程的特点:依赖进程(内存共享,CPU使用独立)启动开销小,线程之间共享数据容易,方便通信,线程不安全。
如何使用上面的技术完成多任务?
代码如何做?
Python:
两种方式:函数和类
Python2:thread
Python3:_thread
threading(功能相比_thread更强大,推荐使用)
函数方式
import threading
import time
def someting():
for i in range(1,11):
print(i)
time.sleep(1)
threading._start_new_thread(someting(),())
print("main")
类方式
class Mythread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
print("Mythread")
def run(self):
for i in range(1,11):
print(i)
time.sleep(1)
def start(self):
print("开始Mythread")
super().start()
t=Mythread()
t2 = Mythread()
t.start()
t2.start()
注意:
start:注意如果重写了start一定要调用父类的start
run:是用户的任务方法,会在start之后自动调用
join:线程阻塞方法,哪个线程调用那个线程阻塞,直到join中指定的时间,或者run方法内代码执行完成
线程同步
当多个线程同时进行任务时,为了保证不会有多个线程同时对同一个数据进行操作造成不可预料的后果,所以有了锁的概念,我们通过锁来使多线程任务更加安全。
lock = threading.Lock()
cond = threading.Condition(lock=lock)
锁当然有锁定和未锁定两种状态,当一个线程要访问共享数据时,必须要先获得锁定,如果已经有别的线程获得锁定,那么就进入暂停状态,等别的线程把锁释放后,再进行操作。
class Thread1(threading.Thread):
def run(self):
for i in range(1,11):
if i==3:
cond.acquire()
cond.wait() #等待
cond.release()
print(i)
time.sleep(1)
class Thread2(threading.Thread):
def run(self):
for i in range(30,19,-1):
print(i)
time.sleep(1)
cond.acquire()
cond.notify()
cond.release()
lock = threading.Lock()
cond = threading.Condition(lock=lock)
t1 = Thread1()
t2 = Thread2()
t1.start()
t2.start()
上面代码无共享数据,只是看一下两个线程通过锁完成的线程同步
class Huofu(threading.Thread):
def __init__(self,name=None):
threading.Thread.__init__(self)
self.name = name
def run(self):
while True:
cond.acquire()
if len(guo)==0:
for i in range(1,11):
guo.append(i)
print('做出第{0}个馒头'.format(i))
time.sleep(1)
cond.notify_all()
cond.release()
cond2.acquire()
cond2.wait()
cond2.release()
class Chihuo(threading.Thread):
def __init__(self,name=None):
threading.Thread.__init__(self)
self.name = name
def run(self):
while True:
mantou=None
cond.acquire()
if len(guo)==0:
cond2.acquire()
cond2.notify()
cond2.release()
cond.wait()
else:
mantou=guo.pop()
cond.release()
if mantou is not None:
print('{0}正在吃{1}'.format(self.name,mantou))
time.sleep(random.randint(1,5))
guo = []
lock = threading.Lock()
cond = threading.Condition(lock=lock)#吃的锁
lock2 = threading.Lock()
cond2 = threading.Condition(lock=lock2)#蒸馒头的锁
Huofu(name='做饭和尚').start()
Chihuo(name='吃饭和尚1').start()
Chihuo(name='吃饭和尚2').start()
Chihuo(name='吃饭和尚3').start()
上面代码就是多线程共享一个数据,一个线程完成添加数据,另外三个线程消耗数据;
当无数据时,Huofu线程会添加数据到固定数量,然后唤醒Chihuo进行数据消耗,等数据消耗完成之后再唤醒Huofu