python2多线程_python_并发编程——多线程2

1.互斥锁

importtimefrom threading importThread,Lockdeffunc1(lock):globaln

lock.acquire()#加锁

temp =n

time.sleep(0.2)

n= temp -1lock.release()#解锁

n= 10t_list=[]

lock=Lock()for i in range(10):

t1= Thread(target=func1,args=(lock,))

t1.start()

t_list.append(t1)for i int_list:

i.join()print(n)

结果:

  牺牲了执行的速度,但保证了数据的安全性。

2.递归锁

from threading importThread,RLockdeffunc1(name):

lock1.acquire()print('{}拿到第一把钥匙!'.format(name))

lock2.acquire()print('{}拿到第二把钥匙!'.format(name))print('{}进入了房间'.format(name))

lock2.release()#归还第二把钥匙

lock1.release() #归还第一把钥匙

lock1= RLock() #锁1

lock2 = RLock() #锁2

for i in range(10):

Thread(target=func1,args=(i,)).start()

结果:

  当同时需要拿到两把钥匙才可以执行代码时,容易出现分别两个不同的线程,每个线程各拿到一把钥匙时,就会出现死锁,所有递归锁就可以解决这样的问题。

3.信号量

from threading importSemaphore,Threadimporttimedeffunc(sem,a,b):

sem.acquire()

time.sleep(1) #增加1秒之的间隔,更容易看出执行结果

print(a+b)

sem.release()

sem= Semaphore(4) #定义一个信号量对象,设置好信号量的数量

for i in range(10):

t= Thread(target=func,args=(sem,i,i+5)) #将信号来传递进子线程要执行的函数

t.start()

结果:只能同时有4个进程访问函数。

4.事件

当事件被创建出来的时候,他的状态是False,事件的状态可以控制wait(),当事件的状态为True时,wait()非阻塞,当事件状态为False时,wait()阻塞。

有两个方法可以修改事件的状态,clear():设置事件的状态为False,set():设置事件的状态为True。

应用:多线程模拟检测数据库链接状态:

importtimeimportrandomfrom threading importThread,Eventdefconnect_db(e):

count= 0 #计数器

while count < 3:

e.wait(1) #根据事件e的状态选择是否阻塞,括号里面加参数,设置阻塞时间1秒

if e.is_set() == True: #is_set():检测事件e的状态

print('数据库链接成功!')break

else:

count+= 1

print('第{}次链接数据库失败!'.format(count))else:print('连接数据库超时!')defcheck_web(e):

time.sleep(random.randint(0,3)) #模拟网络延时0-3s

e.set() #将事件对象状态设置为True

e= Event() #创建一个事件对象

t1 = Thread(target=connect_db,args=(e,))

t2= Thread(target=check_web,args=(e,))

t1.start()

t2.start()

结果:

5.条件

条件类似一个高级的锁,他除了acquire()方法和release()方法之后还有两个方法,wait()方法和notify()方法。

一个条件被创建之初,默认会有一个状态,这个状态会影响wait()方法,一直处于等待状态。

notify(int数据类型)方法的括号中有一个int类型的数值,这个方法的作用是制作钥匙,括号中填写制作钥匙的数量。

wait和notify 都需要在acquire和release之间。

from threading importThread,Conditiondeffunc(con,i):

con.acquire()

con.wait()#等待

print('在第{}个函数中!'.format(i))

con.release()

con= Condition() #创建一个条件对象

for i in range(10):

Thread(target=func,args=(con,i)).start()whileTrue:

num= int(input('输入一个整数:'))

con.acquire()

con.notify(num)#造钥匙

con.release()

结果:

  造多少个钥匙,就多少个线程访问函数。

6.定时器

from threading importTimerdeffunc():print('定时开启线程!')#两个值 第一个:时间,以秒为单位,第二个:函数名

Timer(3,func).start() #3秒周之后开启一个线程执行函数func

结果:3秒后,打印‘定时开启线程!

7.队列

队列是安全的,队列中的数据先进先出。

importqueue

q= queue.Queue(10) #创建一个队列对象,设置队列大小

for i in range(10):

q.put(i)#向队列中存数据

for i in range(10):print(q.get()) #从队列中获取数据

结果:

当队列中没有值时,还继续用get方法获取队列中的值,会一直等待,当队列中值满了的时候,还继续用put方法想队列中存放数据,也会一直阻塞。

put_nowait()方法:

importqueue

q= queue.Queue(10) #创建一个队列对象,设置队列大小

for i in range(11):

q.put(i)#向队列中存数据

q.put_nowait() #当队列中值满了的时候,再继续向队列中存值,会报错

结果:

get_nowait()方法:

importqueue

q= queue.Queue(10)

q.put('wdc')print(q.get())

q.get_nowait()#当队列中没有值的时候,会报错

结果:

8.栈

先进后出。

importqueue

q= queue.LifoQueue(10) #创建一个栈对象,大小为10

for i in range(10):

q.put(i)for i in range(10):print(q.get())

结果:

9.优先级队列

importqueue

q= queue.PriorityQueue() #创建一个优先级队列对象

q.put((20,'a')) #向优先级队列放数据时,要放一个元组,第一个代表优先级,第二个是要存放的数据

q.put((30,'b'))

q.put((10,'c'))print(q.get())

结果:

  先获取优先级数值小的元组。

importqueue

q= queue.PriorityQueue() #创建一个优先级队列对象

q.put((10,'s'))

q.put((20,'a')) #向优先级队列放数据时,要放一个元组,第一个代表优先级,第二个是要存放的数据

q.put((30,'b'))

q.put((10,'c'))

q.put((10,'d'))print(q.get())

结果:

 当优先级相同时,会根据值的ascii编码的顺序获取。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值