线程是进程中一个“单一的连续控制流程”/执行路径
多线程程序的执行顺序是不确定的,当执行到sleep时,线程将被阻塞(bloceed),到sleep结束后,线程进入就绪(runable)状态等待调度。而线程调度将自行选择一个线程执行。
py中的thread模块是比较底层的模块,而threading模块是对thread模块做了一些包装,使之可以更方便的被调用。
import os,time,random,threading
def say(name):
print('%sSorry'%name)
if __name__=='__main__':
t=threading.Thread(target=say,args=('MM',))
t.start()
t.join()
'''
MMSorry
'''
import os,time,random,threading
class Thread_Test(threading.Thread):
def __init__(self,name):
#注意:初始化要放在参数赋值前面
threading.Thread.__init__(self)
self.name=name
def run(self):
print('当前进程名%s'%(self.name,))
if __name__=='__main__':
t=Thread_Test('MM')
t.start()
t.join()
'''
当前进程名MM
'''
当然也可以使用给方法传参的方式
import os,time,random,threading
num=100
def fun1():
#声明num为全局变量
global num
for i in range(3):
num+=1
print(str(num),'>>>fun1')
def fun2():
global num
print(num,'>>>fun2')
t1=threading.Thread(target=fun1)
t1.start()
time.sleep(1)
t2=threading.Thread(target=fun2)
t2.start()
'''
通过结果可以看出,两个线程共享num变量
101 >>>fun1
102 >>>fun1
103 >>>fun1
103 >>>fun2
'''
import os,time,random,threading
def fun1(name):
local.name=name
fun2()
def fun2():
name=local.name
print(name)
#创建全局的ThreadLocal对象
local=threading.local()
for i in range(5):
threading.Thread(target=fun1,args=(i,)).start()
import os,time,random,threading
num=100
def fun1():
#声明num为全局变量
global num
#获取锁
lock.acquire()
try:
for i in range(100):
num += 1
print(str(num), '>>>fun1')
finally:
#释放锁
lock.release()
def fun2():
global num
lock.acquire()
try:
for i in range(100):
num += 1
print(str(num), '>>>fun2')
finally:
lock.release()
lock=threading.Lock()
t1=threading.Thread(target=fun1)
t1.start()
time.sleep(1)
t2=threading.Thread(target=fun2)
t2.start()
线程间共享多个资源时,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会进入死锁状态。
import os,time,random,threading
num=100
def fun1():
#声明num为全局变量
global num
#获取锁
lock1.acquire()
try:
print('>>>fun1')
time.sleep(1)
lock2.acquire()
for i in range(100):
num += 1
print(str(num), '>>>fun1')
lock2.release()
finally:
#释放锁
lock1.release()
def fun2():
global num
lock2.acquire()
print('>>>fun2')
time.sleep(1)
try:
lock1.acquire()
for i in range(100):
num += 1
print(str(num), '>>>fun2')
lock1.release()
finally:
lock2.release()
lock1=threading.Lock()
lock2=threading.Lock()
t1=threading.Thread(target=fun1)
t2=threading.Thread(target=fun2)
t1.start()
t2.start()
'''
>>>fun1
>>>fun2
'''
py的Queue模块提供了同步的,线程安全的队列类
这些队列都是实现了锁原语(原子操作),可以在多线程中直接使用。
from queue import Queue,LifoQueue,PriorityQueue
import os,time,random,threading
class Producer(threading.Thread):
global queue
def run(self):
count=0
while True:
if queue.qsize()<1000:
count+=1
msg='生产者'+str(count)
queue.put(msg)
print(msg)
class Consumer(threading.Thread):
def run(self):
global queue
while True:
if queue.qsize()>0:
msg=self.name+'消费了'+queue.get()
print(msg)
#queue=Queue()
queue=PriorityQueue()
#queue=LifoQueue()
for i in range(5):
Producer().start()
for i in range(5):
Consumer().start()