一、死锁与递归锁(了解)

1 死锁

程序中如果出现多个锁操作容易造成死锁现象

from threading import Thread,Lock

import time
# 实例化两个锁对象
a = Lock()
b = Lock() class MyThread(Thread):
def run(self):
self.func1()
self.func2() def func1(self):
a.acquire() # 10个线程去抢和这个锁
print(self.name)
b.acquire() # 抢到a的才能抢b
print(self.name)
b.release()
a.release() # 施放a的时候 线程2瞬间抢到了a开始执行 def func2(self):
b.acquire() # 线程1抢到b和线程2互相卡死,因为需要对方的锁才能施放自己的锁
print(self.name)
time.sleep(2)
a.acquire()
print(self.name)
a.release()
b.release() for i in range(10):
t = MyThread()
t.start()

2 递归锁

"""
递归锁的特点
可以被连续的acquire和release
但是只能被第一个抢到这把锁执行上述操作
它的内部有一个计数器 每acquire一次计数加一 每realse一次计数减一
只要计数不为0 那么其他人都无法抢到该锁
"""
# 将上述的
mutexA = Lock()
mutexB = Lock()
# 换成
mutexA = mutexB = RLock()

二、信息量

信号量在不同的阶段可能对应不同的技术点

在并发编程中信号量指的是锁

from threading import Thread, Semaphore
import time
import random sm = Semaphore(5) # 括号内写数字 写几就表示开设几个坑位
# 内置方法和锁一样,抢和施放
# 区别在于信号量可以规定一次性抢锁的最大数量 def task(name):
sm.acquire()
print('%s 正在蹲坑'% name)
time.sleep(random.randint(1, 5))
sm.release() if __name__ == '__main__':
for i in range(20):
t = Thread(target=task, args=('伞兵%s号'%i, ))
t.start()

三、Event事件

一些进程或者线程遇到等待另外一些进程或者线程运行完毕之后才能运行,类似发射信号

from threading import Thread, Event
import time event = Event() # 造了一个红绿灯 def light():
print('红灯亮着的')
time.sleep(3)
print('绿灯亮了')
# 告诉等待红灯的人可以走了
event.set() def car(name):
print('%s 车正在灯红灯'%name)
event.wait() # 等待别人给你发信号
print('%s 车加油门飙车走了'%name) if __name__ == '__main__':
t = Thread(target=light)
t.start() for i in range(20):
t = Thread(target=car, args=('%s'%i, ))
t.start()

四、三种优先级数据操作

同一个进程下多个线程数据共享,但为了保证数据安全,我们需要用到以下三种数据操作

1 队列

原则:先进先出

import queue

q = queue.Queue(3)

q.put(1)
q.put(2)
q.put(3) print(q.empty()) # 判断队列是否为空
print(q.full()) # 判断队列是否为满 q.get()
q.get()
q.get()
q.get(timeout=3) # 等待3秒再取数据,如果没有就报错
q.get_nowait() # 不等待,没有数据就报错

2 堆栈

原则:先进后出

堆栈
import queue q = queue.LifoQueue(3) # last in first out q.put(1)
q.put(2)
q.put(3) print(q.get())
>>> 3

3 自定义优先级

import queue

q = queue.PriorityQueue(3) # 上传数据时要先上传一个该数字排名,排名小的现出来

q.put(('5',1))
q.put(('0',1))
q.put(('-1',1)) print(q.get_nowait())
>>> ('-1',1)

五、进程池和线程池

之前在tcp实现并发的时候我们是来一个用户就启用一个线程或者进程去为用户服务
但是计算机的硬件资源目前还无法支持我们无限制的开发线程
所以用到了池的概念
池相当于缓冲地带,让我们可以保证计算机在正常运行的情况下最大限度的利用它
它降低了程序的运行效率,但是保证了计算机的安全 如果把计算机比喻成一个小池子你限定了池子最大容量是1,你要喂食,池子就会先产生一条鱼,给你喂,其他人想喂就得等你结束,过来喂的是同一条鱼 而如果不用池的概念去限定,每个人来池子都会给人产生一条鱼来服务,鱼多了,池子就炸了。

基本使用

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import time
import os # pool = ThreadPoolExecutor(5)# 线程池里只有5个线程
pool = ProcessPoolExecutor(2)# 进程池里只有5个进程
# 括号内可以传数字 不传的话默认会开设当前计算机cpu个数五倍的线程
# 池子造出来之后 里面会固定存在五个线程
# 这个五个线程不会出现重复创建和销毁的过程
# 池子的使用非常的简单
# 你只需要将需要做的任务往池子中提交即可 自动会有人来服务你 def text(n):
print(os.getpid())
time.sleep(3)
return n**n def callback(n):
print(n.result()) if __name__ == '__main__':
res = pool.submit(text,2) # 返回值是一个对象 # print('主') # 异步提交,判断异步的方式,在任务提交后得到返回值之前能不能执行代码 # print(res.result()) # 得到的是提交任务的返回值 t_list = []
for i in range(10):
pool.submit(text,i).add_done_callback(callback) # 自定义异步回调机制,在任务得到返回值的时候直接调用里面的函数
# 这种回调机制可以想象为,在提交任务后,直接运行下面的代码,什么时候有返回值了,会立刻调用该方法,相当于埋下了定时炸弹,返回值来了就触发
# res = pool.submit(text,i).result() # 这种得到结果的方式是同步
# t_list.append(res)
# pool.shutdown() # 关闭所有线程
# for i in t_list:
# print(i)

六、协程

  • 进程:资源单位
  • 线程:执行单位
  • 协程:意淫出来的
    • 为了在多线程实现并发,我们在多线程中出现io情况都切换走,去执行其他线程,这样就会让计算机看起来一直在运行没有中断过。从而提升了程序的运行效率

七、gevent模块

from gevent import monkey;monkey.patch_all()
# 猴子补丁,用来检测程序里出现的io操作
import time
from gevent import spawn def a():
print('a')
time.sleep(2)
print('a end') def b():
print('b')
time.sleep(4)
print('b end') start = time.time()
g1 = spawn(a)
g2 = spawn(b)
g1.join()
g2.join()# 等待任务执行完再执行后面的代码
print(time.time()-start) # 4.015194654464722 实现了io时间切换操作,用户只需等待最长的任务时间

八、协程实现tcp并发

#服务端
import socket
from gevent import monkey;monkey.patch_all()
from gevent import spawn def communication(conn):
while True:
try:
msg = conn.recv(1024)
if len(msg) == 0:break
conn.send(msg.upper())
except Exception as e:
print(e)
break
conn.close() def sever(ip,port):
s = socket.socket()
s.bind((ip, port))
s.listen(5)
while True:
conn,addr = s.accept()
communication(conn) if __name__ == '__main__':
g = spawn(sever,'127.0.0.1',8080)
g.join() # 客户端 import socket
from threading import Thread,current_thread def client():
s = socket.socket()
s.connect(('127.0.0.1', 8080))
n = 0
while True:
msg = '%s say hello %s' % (current_thread().name, n)
n += 1
s.send(msg.encode('utf-8'))
data = s.recv(1024)
print(data.decode('utf-8')) if __name__ == '__main__':
for i in range(50):
t = Thread(target=client)
t.start()

day41 几个琐碎知识点的更多相关文章

  1. Java琐碎知识点

    jps命令是JDK1.5提供的一条显示当前用户的所有java进程pid的指令,类似Linux上的ps命令简化版,Windows和linux/unix平台都可以用比较常用的参数:-q:只显示pid,不显 ...

  2. linux琐碎知识点

    1.awk的使用方式,pattern支持正则表达式 awk 'pattern{action}' {filenames} 其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找 ...

  3. linux学习之一些琐碎知识点

    一.python 问:django中project和app之间到底有什么不同? 答:他们的区别就是一个是配置,另一个是代码. 一个project包含很多个django app以及对它们的配置.技术上, ...

  4. Java知识点:琐碎知识点(3)

    零碎 switch(x),x只可以是enum或byte.short.char.int. 枚举在switch-case语句作为标签时必须是枚举常量的非限定名称,否则Compile Error. Enum ...

  5. Java知识点:琐碎知识点(2)

    49个关键字一览 abstract default if private this boolean do implements protected throw break double import ...

  6. Java知识点:琐碎知识点(1)

    Java基本介绍 SUN:Stanford University NetworkJava之父:James GoslingJava的跨平台性因为有Java虚拟机,运行class文件.Java吉祥物:Du ...

  7. ROS机器人编程实践----琐碎知识点

    amcl原理: amcl将激光传感器数据与从地图预估的传感器数据相比较,给出可能的位姿.如果传感器数据和某个候选位姿处的预测数据相同,amcl就会给这个位姿一个较高的概率,反之,就会降低这个概率.概率 ...

  8. CSS琐碎知识点(持续补充)

    一.字体单位,pt?px?em?rem? pt:磅,一种固定长度的绝对的度量单位,是能够使用测量设备测得的长度,印刷业上经常使用,一般用于页面打印排版. px:屏幕设备上能显示出的最小的一个物理点,这 ...

  9. HTML琐碎知识点(持续补充)

    一.table标签 <table> <thead> <tr> <th>111</th> </tr> </thead> ...

随机推荐

  1. 一个基于Consul的.NET Leader选举类库

    前段时间有传言说Consul将不能在我国继续使用,后被查明是因法律问题Vault企业版产品不能在国内销售.Valut和Consul都是HashiCorp公司的产品,并且都推出了开源版本,继续使用开源版 ...

  2. 面试了 6 轮 Google 中国 之后,还是挂了

    去年换工作的时候, 面试了一下 Google (这里说的是 Google 中国哈), 来了个 Google 面试六轮游, 结果是没通过.

  3. JVM内存结构详解

    从java编程语言说起... 1. Java编程语言简介 1.1 编程语言概述 系统级和应用级 系统级:C,C++,go,erlang 应用级:C#,Java,Python,Perl,Ruby,php ...

  4. 自己动手实现深度学习框架-8 RNN文本分类和文本生成模型

    代码仓库: https://github.com/brandonlyg/cute-dl 目标         上阶段cute-dl已经可以构建基础的RNN模型.但对文本相模型的支持不够友好, 这个阶段 ...

  5. .Net 对于PDF生成以及各种转换的操作

    前段时间公司的产品,要做一个新功能,签章(就是把需要的数据整理成PDF很标准的文件,然后在盖上我们在服务器上面的章) 然后我就在百度上找了找,发现搞PDF的类库很少,要么就要钱,要么就有水印,破解版的 ...

  6. Linux下常用命令(持续更新)

    l: 列举目录下的所有文件 ll: 显示详细属性 pwd: 查看当前所在完整路径 cd: 变更文件夹(变更到根目录:cd + /:变更到上级目录:cd + ..) sudo: 允许利用超级用户权限执行 ...

  7. Eplan PLC连接点模块为什么不显示“路径功能文本”,已解决

    Eplan PLC连接点模块为什么不显示“路径功能文本”,已解决 如果“路径功能文本”的文字开头的位置没有对准PLC模块的中心,PLC连接点模块就不会显示.

  8. Docker中使用RabbitMQ

    安装Docker yum install docker //安装完成以后,可以查看一下docker的版本 docker -v //Docker version 1.13.1, build 64e998 ...

  9. thinkphp3.2 where 条件查询

    thinkphp3.2 where 条件查询 在连贯操作中条件where的操作有时候自己很晕,所以整理下,有助于使用 查询条件 支持的表达式查询,tp不区分大小写 含义 TP运算符 SQL运算符 例子 ...

  10. Appium 自动化实例代码

    自动化连接 B站 开始 如果下载node.js 的话 可以检查一下appium环境 命令行: appium-doctor 如果没有 可以安装   appium-doctor :npm install ...