线程,进程:线程是操作系统能够进行运算调度的最小单位。
一个线程就是一堆指令集合
GIL:(Global Interpreter Lock 全局解释器锁)只有cpython有GIL。 作用:在同一时刻只能有一个线程进入解释器,因为有GIL的存在,所以Python不能使用多个处理器同时处理多个线程。
GIL是加在解释器上的。
进程:一个程序的实例,可以多进程处理
线程可以数据共享,进程不能实现共享
结论:在Python里如果处理的任务是IO密集型的,可以用多线程,如果是计算密集型的,改C。
join是阻塞用的,在子线程完成运行之前,这个子线程的父线程将一直被阻塞。
daemon守护线程(主线程结束之后不再等待子线程运行,直接结束)
#线程就是一堆指令集
import time
import threading
begin=time.time()
def foo(n):
print('foo%s'%n)
time.sleep(1) #不占CPU
print('end foo')
def bar(n):
print('bar%s'%n)
time.sleep(2)
print('end bar')
# foo()
# bar()
t1=threading.Thread(target=foo,args=(1,))
t2=threading.Thread(target=bar,args=(2,))
t1.start()
t2.start()
print('.....in the main........')
t1.join()
t2.join()
end=time.time()
print(end-begin)
====================================================================================
from time import ctime,sleep
import threading
def music(func):
for i in range(2):
print('i was listening to %s,%s'%(func,ctime()))
sleep(1)
print('end listening %s'%ctime())
def move(func):
for i in range(2):
print('i was watching at the %s! %s'%(func,ctime()))
sleep(5)
print('end watching at the %s'%ctime())
threads=[]
t1=threading.Thread(target=music,args=('七里香,',))
threads.append(t1)
t2=threading.Thread(target=move,args=('阿甘正传,',))
threads.append(t2)
if __name__=='__main__':
# music(u'七里香')
# move(u'世界末路')
t2.setDaemon(True)
for t in threads:
# t.setDaemon(True)
t.start()
# t.join()
# t.join()
print('all over is %s'%ctime())
print(threading.current_thread()) #当前执行的线程
print(threading.active_count()) #当前或者的线程
print()
# =========================通过类创建线程===============================
import threading
import time
class MyThread(threading.Thread):
def __init__(self, num):
threading.Thread.__init__(self)
self.num = num
def run(self): # 定义每个线程要运行的函数
print("running on number:%s" % self.num)
time.sleep(3)
if __name__ == '__main__':
t1 = MyThread(1)
t2 = MyThread(2)
t1.start()
t2.start()
===================================================================================
同步锁
import time
import threading
def addNum():
global num #在每个线程中都获取这个全局变量
# num-=1 #最后结果是0,执行很快,CPU来不及切换,所以不会产生死锁
#开锁 acquire ,解锁 release
r.acquire()
temp=num
print('ok')
time.sleep(0.01)
num =temp-1 #对此公共变量进行-1操作
r.release()
num = 100 #设定一个共享变量
thread_list = []
#加锁
r=threading.Lock()
for i in range(100):
t = threading.Thread(target=addNum)
t.start()
# t.join() #程序变成串行
thread_list.append(t)
for t in thread_list: #等待所有线程执行完毕
t.join()
print('final num:', num )
# import time
# import threading
# def addNum():
# global num #在每个线程中都获取这个全局变量
# # num-=1
# lock.acquire()
# temp=num
# print('--get num:',num )
# time.sleep(0.01)
# num =temp-1 #对此公共变量进行-1操作
# lock.release()
# num = 100 #设定一个共享变量
# thread_list = []
# lock=threading.Lock()
# for i in range(100):
# t = threading.Thread(target=addNum)
# t.start()
# thread_list.append(t)
#
# # for t in thread_list: #等待所有线程执行完毕
# # t.join()
#
# print('final num:', num )
==================================================================================
死锁和递归锁
import threading,time
class myThread(threading.Thread):
def doA(self):
# lockA.acquire()
lock.acquire()
print(self.name,"gotlockA1",time.ctime())
time.sleep(3)
# lockB.acquire()
lock.acquire()
print(self.name,"gotlockB1",time.ctime())
# lockB.release()
# lockA.release()
lock.release()
lock.release()
def doB(self):
# lockB.acquire()
lock.acquire()
print(self.name,"gotlockB2",time.ctime())
time.sleep(2)
# lockA.acquire()
lock.acquire()
print(self.name,"gotlockA2",time.ctime())
# lockA.release()
# lockB.release()
lock.release()
lock.release()
def run(self):
self.doA()
time.sleep(0.1)
self.doB()
if __name__=="__main__":
# lockA=threading.Lock()
# lockB=threading.Lock()
lock=threading.RLock() #递归锁,将上面的lockA和lockB全部替换成lock
threads=[]
for i in range(5):
threads.append(myThread())
for t in threads:
t.start()
for t in threads:
t.join()#等待线程结束,后面再讲。
#===============================================================
class Account():
def __int__(self,id,money,r):
self.id=id
self.balance=money
def withdraw(self,num):
r.acquire()
self.balance-=num
r.release()
def repay(self,num):
r.acquire()
self.balance+=num
r.release()
def abc(self,num):
r.acquire()
self.withdraw()
self.balance+=num
r.release()
def transer(_from,to,count):
r.acquire()
_from.withdraw(count)
to.repay(count)
r.release()
r=threading.RLock()
a1=Account('alex',10)
a2=Account('abc',20)
t1=threading.Thread(target=transer,args=(a1,a2,100))
t2=threading.Thread(target=transer,args=(a2,a1,200))
t1.start()
t2.start()