网路线程的锁

#!/usr/bin/env python

-- coding:utf-8 --

线程中是不是会产生数据不安全

# 共享内存

a = 0

def add_f():

global a

for i in range(200000):

a += 1

def sub_f():

global a

for i in range(200000):

a -= 1

from threading import Thread

t1 = Thread(target=add_f)

t1.start()

t2 = Thread(target=sub_f)

t2.start()

t1.join()

t2.join()

print(a)

a = 0

def func():

global a

a -= 1

import dis

dis.dis(func)

即便是线程 即便有GIL 也会出现数据不安全的问题

# 1.操作的是全局变量
# 2.做一下操作
    # += -= *= /+ 先计算再赋值才容易出现数据不安全的问题
    # 包括 lst[0] += 1  dic['key']-=1

a = 0

def func():

global a

a += 1

import dis

dis.dis(func)

a = 0
def add_f(lock):
global a
for i in range(200000):
with lock:
a += 1

def sub_f(lock):
global a
for i in range(200000):
with lock:
a -= 1

from threading import Thread,Lock

lock = Lock()

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

t1.start()

t2 = Thread(target=sub_f,args=(lock,))

t2.start()

t1.join()

t2.join()

print(a)

加锁会影响程序的执行效率,但是保证了数据的安全

互斥锁是锁中的一种:在同一个线程中,不能连续acquire多次

from threading import Lock

lock = Lock()

lock.acquire()

print(’*’*20)

lock.release()

lock.acquire()

print(’-’*20)

lock.release()

单列模式

#!/usr/bin/env python

-- coding:utf-8 --

import time
from threading import Lock
class A:
__instance = None
lock = Lock()
def new(cls, *args, **kwargs):
with cls.lock:
if not cls.__instance:
time.sleep(0.1)
cls.__instance = super().new(cls)
return cls.__instance
def init(self,name,age):
self.name = name
self.age = age

def func():
a = A(‘alex’, 84)
print(a)

from threading import Thread
for i in range(10):
t = Thread(target=func)
t.start()

#!/usr/bin/env python

-- coding:utf-8 --

import time
from threading import Thread,Lock
noodle_lock = Lock()
fork_lock = Lock()
def eat1(name,noodle_lock,fork_lock):
noodle_lock.acquire()
print(’%s抢到面了’%name)
fork_lock.acquire()
print(’%s抢到叉子了’ % name)
print(’%s吃了一口面’%name)
time.sleep(0.1)
fork_lock.release()
print(’%s放下叉子了’ % name)
noodle_lock.release()
print(’%s放下面了’ % name)

def eat2(name,noodle_lock,fork_lock):
fork_lock.acquire()
print(’%s抢到叉子了’ % name)
noodle_lock.acquire()
print(’%s抢到面了’%name)
print(’%s吃了一口面’%name)
time.sleep(0.1)
noodle_lock.release()
print(’%s放下面了’ % name)
fork_lock.release()
print(’%s放下叉子了’ % name)

lst = [‘alex’,‘wusir’,‘taibai’,‘yuan’]
Thread(target=eat1,args=(lst[0],noodle_lock,fork_lock)).start()
Thread(target=eat2,args=(lst[1],noodle_lock,fork_lock)).start()
Thread(target=eat1,args=(lst[2],noodle_lock,fork_lock)).start()
Thread(target=eat2,args=(lst[3],noodle_lock,fork_lock)).start()

# 互斥锁
    # 在一个线程中连续多次acquire会死锁
# 递归锁
    # 在一个线程中连续多次acquire不会死锁
# 死锁现象
    # 死锁现象是怎么发生的?
        # 1.有多把锁,一把以上
        # 2.多把锁交替使用
# 怎么解决
    # 递归锁 —— 将多把互斥锁变成了一把递归锁
        # 快速解决问题
        # 效率差
    # ***递归锁也会发生死锁现象,多把锁交替使用的时候
    # 优化代码逻辑
        # 可以使用互斥锁 解决问题
        # 效率相对好
        # 解决问题的效率相对低

#!/usr/bin/env python

-- coding:utf-8 --

from threading import RLock

rlock = RLock()

rlock.acquire()

print(’*’*20)

rlock.acquire()

print(’-’*20)

rlock.acquire()

print(’*’*20)

在同一个线程中,可以连续acuqire多次不会被锁住

递归锁:

# 好 :在同一个进程中多次acquire也不会发生阻塞
# 不好 :占用了更多资源

import time
from threading import RLock,Thread

noodle_lock = RLock()

fork_lock = RLock()

noodle_lock = fork_lock = RLock()
print(noodle_lock,fork_lock)
def eat1(name,noodle_lock,fork_lock):
noodle_lock.acquire()
print(’%s抢到面了’%name)
fork_lock.acquire()
print(’%s抢到叉子了’ % name)
print(’%s吃了一口面’%name)
time.sleep(0.1)
fork_lock.release()
print(’%s放下叉子了’ % name)
noodle_lock.release()
print(’%s放下面了’ % name)

def eat2(name,noodle_lock,fork_lock):
fork_lock.acquire()
print(’%s抢到叉子了’ % name)
noodle_lock.acquire()
print(’%s抢到面了’%name)
print(’%s吃了一口面’%name)
time.sleep(0.1)
noodle_lock.release()
print(’%s放下面了’ % name)
fork_lock.release()
print(’%s放下叉子了’ % name)

lst = [‘alex’,‘wusir’,‘taibai’,‘yuan’]
Thread(target=eat1,args=(lst[0],noodle_lock,fork_lock)).start()
Thread(target=eat2,args=(lst[1],noodle_lock,fork_lock)).start()
Thread(target=eat1,args=(lst[2],noodle_lock,fork_lock)).start()
Thread(target=eat2,args=(lst[3],noodle_lock,fork_lock)).start()

#!/usr/bin/env python

-- coding:utf-8 --

import time
from threading import Lock,Thread
lock = Lock()
def eat1(name,noodle_lock,fork_lock):
lock.acquire()
print(’%s抢到面了’%name)
print(’%s抢到叉子了’ % name)
print(’%s吃了一口面’%name)
time.sleep(0.1)
print(’%s放下叉子了’ % name)
print(’%s放下面了’ % name)
lock.release()

def eat2(name,noodle_lock,fork_lock):
lock.acquire()
print(’%s抢到叉子了’ % name)
print(’%s抢到面了’%name)
print(’%s吃了一口面’%name)
time.sleep(0.1)
print(’%s放下面了’ % name)
print(’%s放下叉子了’ % name)
lock.release()

lst = [‘alex’,‘wusir’,‘taibai’,‘yuan’]
Thread(target=eat1,args=(lst[0],noodle_lock,fork_lock)).start()
Thread(target=eat2,args=(lst[1],noodle_lock,fork_lock)).start()
Thread(target=eat1,args=(lst[2],noodle_lock,fork_lock)).start()
Thread(target=eat2,args=(lst[3],noodle_lock,fork_lock)).start()

#!/usr/bin/env python

-- coding:utf-8 --

import queue

线程之间的通信 线程安全

from queue import Queue # 先进先出队列

q = Queue(5)

q.put(0)

q.put(1)

q.put(2)

q.put(3)

q.put(4)

print(‘444444’)

print(q.get())

print(q.get())

print(q.get())

print(q.get())

print(q.get())

使用多线程 实现一个请求网页 并且把网页写到文件中

生产者消费者模型来完成

5个线程负责请求网页 把结果放在队列里

2个线程 负责从队列中获取网页代码 写入文件

from queue import LifoQueue # 后进先出队列

last in first out 栈

lfq = LifoQueue(4)

lfq.put(1)

lfq.put(3)

lfq.put(2)

print(lfq.get())

print(lfq.get())

print(lfq.get())

先进先出

# 写一个server,所有的用户的请求放在队列里
    # 先来先服务的思想

后进先出

# 算法

优先级队列

# 自动的排序
# 抢票的用户级别 100000 100001
# 告警级别

from queue import PriorityQueue

pq = PriorityQueue()

pq.put((10,‘alex’))

pq.put((6,‘wusir’))

pq.put((20,‘yuan’))

print(pq.get())

print(pq.get())

print(pq.get())

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值