线程
1、多线程的理解
多进程和多线程都可以执行多个任务,线程是进程的一部分。线程的特点是线程之间可以共享内存和变量,资源消耗少,缺点是线程之间的同步和加锁比较麻烦。
2、python创建多线程
在Python中,同样可以实现多线程,有两个标准模块thread和threading,不过我们主要使用更高级的threading模块。
使用例子:
import time
# def something():
# for i in range(1,11):
# print(i)
# time.sleep(1)
# threading._start_new_thread(something,())
# print("mian....")
# input()
上面只是一个简单的关于线程的示例,简单的实现了使用线程
'''
类的方式start:注意重写了Start一定要调用父类的start
run:使用户的任务方法会在start之后自动调用
join:线程阻塞方法,谁调用join,阻断谁。直到join中指定的时间,或者run代码执行完了
下面用一个小示例来为大家具体介绍一下我们这些方法
'''# 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")
# threading.Thread.start(self)
# print("mian....")
# t=Mythread()
# t.start()
# t.join()
start是启动线程,join是阻塞当前线程,即使得在当前线程结束时,不会退出。从结果可以看到,主线程直到run方法的执行结束之后才结束。
Python中,默认情况下,如果不加join语句,那么主线程不会等到当前线程结束才结束,但却不会立即杀死该线程。
3、线程锁
对于多线程来说,最大的特点就是线程之间可以共享数据,那么共享数据就会出现多线程同时更改一个变量,使用同样的资源,而出现死锁、数据错乱等情况。假设有两个全局资源,a和b,有两个线程thread1,thread2. thread1占用a,想访问b,但此时thread2占用b,想访问a,两个线程都不释放此时拥有的资源,那么就会造成死锁。对于该问题,出现了Lock。 当访问某个资源之前,用Lock.acquire()锁住资源,访问之后,用Lock.release()释放资源。
class Thread1(threading.Thread):def run(self):
for i in range(1,11):
if i==3:
conditio.acquire()#上锁
conditio.wait()
conditio.release()#解锁
print(i)
time.sleep(1)
class Thread2(threading.Thread):
def run(self):
for i in range(30,19,-1):
if i==25:
conditio.acquire()
conditio.notify()
conditio.release()
print(i)
time.sleep(1)
lock=threading.Lock()#锁
conditio=threading.Condition(lock=lock)#锁的方法
Thread1().start()
Thread2().start()
下面为大家展示一个比较经典的例子,他将我刚才为大家介绍的知识点都包括了,大家可以多看看,它主要是用线程的方法来解决一个高并发的事,举得例子使用和尚蒸馒头这样一个通俗易懂的事情,使得大家可以更容易去理解这段代码,大约的用例需求就是四个和尚,一个做馒头的三个吃馒头的,做馒头的需要先做10个馒头然后叫醒三个吃馒头的,之后自己进入休眠,三个和尚一个一个去拿馒头,只要有一个和尚发现没馒头了,就去叫醒做馒头的,之后三个吃馒头的去进行休眠就这样一直循环。
class zhengThread(threading.Thread): def __init__(self,name=None): threading.Thread.__init__(self); self.name=name def run(self): while True: condition.acquire() if len(guo) == 0: for i in range(1,11): guo.append(i) print("做出第{0}个馒头".format(i)) time.sleep(1) condition.notify_all() condition.release() condition2.acquire() condition2.wait() condition2.release() class chiThread(threading.Thread): def __init__(self,name=None): threading.Thread.__init__(self); self.name=name def run(self): while True: mantou=None condition.acquire() if len(guo) == 0: condition2.acquire() condition2.notify() condition2.release() condition.wait() else: mantou=guo.pop() condition.release() if mantou is not None: print("{0}正在开始吃第{1}个馒头".format(self.name,mantou)) time.sleep(random.choice([1,2,3,4,5])) import random guo=[] lock=threading.Lock() condition=threading.Condition(lock=lock) #吃的锁 lock2=threading.Lock() condition2=threading.Condition(lock=lock2) #蒸的锁 zhengThread(name="大头和尚").start() chiThread(name="白眉和尚").start() chiThread(name="花和尚").start() chiThread(name="牛鼻子和尚").start()
刚才为大家介绍了这么多线程的知识点,线程也不是完美的,他还是有些地方存在着缺陷。
4、线程的缺陷
说了那么多关于多线程的用法,但Python多线程并不能真正能发挥作用,因为在Python中,有一个GIL,即全局解释锁,该锁的存在保证在同一个时间只能有一个线程执行任务,也就是多线程并不是真正的并发,只是交替得执行。假如有10个线程炮在10核CPU上,当前工作的也只能是一个CPU上的线程。
今天就为大家介绍这么多,相信只要大家仔细看了,就可以真正的了解我们python的具体用法。