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

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. ubuntu12.04 qtcreate支持中文输入

    1.sudo apt-get install ibus-qt4 2.重启电脑 reboot

  2. Java 技术网站总结(不停更新)

    Spring Spring 中文手册 Spring 教程 Spring For All Spring 学习笔记 Spring Boot Break易站 Spring Cloud 中文文档 Spring ...

  3. TensorFlow从0到1之TensorFlow逻辑回归处理MNIST数据集(17)

    本节基于回归学习对 MNIST 数据集进行处理,但将添加一些 TensorBoard 总结以便更好地理解 MNIST 数据集. MNIST由https://www.tensorflow.org/get ...

  4. 透过源码看懂Flink核心框架的执行流程

    前言 Flink是大数据处理领域最近很火的一个开源的分布式.高性能的流式处理框架,其对数据的处理可以达到毫秒级别.本文以一个来自官网的WordCount例子为引,全面阐述flink的核心架构及执行流程 ...

  5. css3动画的实例讲解

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. C#数据结构与算法系列(七):约瑟夫问题(Josephu)

    1.介绍 Josephu问题为:设编号为1.2....n的n个人围坐在一圈,约定编号为k(1<=k<=n) 的人从1开始报数, 数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人 ...

  7. FIS3安装与编译

    安装 FIS3 npm install -g fis3 -g 安装到全局目录,必须使用全局安装,当全局安装后才能在命令行(cmd或者终端)找到 fis3 命令 安装过程中遇到问题具体请参考 fis#5 ...

  8. 3、尚硅谷_SSM高级整合_使用ajax操作实现删除的功能

    点击删除的时候,要删除联系人,这里同点击编辑按钮一样给删除按钮添加点击事件的时候不能使用 $(".delete_btn").click(function(){ }); 这种方式,因 ...

  9. Spring IoC 默认标签解析

    前言 本系列全部基于 Spring 5.2.2.BUILD-SNAPSHOT 版本.因为 Spring 整个体系太过于庞大,所以只会进行关键部分的源码解析. 本篇文章主要介绍 Spring IoC 容 ...

  10. SQL注入之Boolean型盲注

    什么是Boolean型注入 Boolean型的注入意思就是页面返回的结果是Boolean型的,通过构造SQL判断语句,查看页面的返回结果是否报错,页面返回是否正常等来判断哪些SQL判断条件时成立的,通 ...