day 34
1 .内容回顾
#__author : 'liuyang'
#date : 2019/4/17 0017 上午 9:01
# 利大于弊,则做之
# 会死于斯,则不去
# 2个 人 晚上 5个题 面试题
# 今晚 7点 考试题
# 五一之前 要考试
#其它内容(40%) 网编并发数据库(60%) #锁
#互斥锁
#能够保护数据的安全性
#保证对于数据的修改操作同一时刻多个进程只有一个进程执行
#进程数据不安全:同时修改文件/数据库/其它共享资源的数据 # 队列---实现了进程之间的通信(IPC) #进程队列 ----进程安全
#从mutltiprocessing 导入Queue
#q = Queue()
#put/get
# 基于管道+管道 ,管道 进程不安全
# 管道 基于文件级别的socket 实现的 import queue
from multiprocessing import Queue
# 生产者消费模型
# put get 两个阻塞方法
# put_nowait(丢数据)/ get_nowait 非阻塞方法
q = Queue(5) #队列里有五个
q.put(1)
q.put(1)
q.put(1)
q.put(1)
q.put(1)
print('_____________')
try :
q.put_nowait(1) #也传一个
except queue.Full:
# 存在这里
pass
# q.put(1)
print('______')
# q.put(1)
print('__')
print(q.get())
print(q.get())
print(q.get())
print(q.get())
print(q.get())
print(q.get())
# print(q.get()) # print(q.get())
# print(q.get())
# print(q.get()) try :
print(q.get_nowait())
except queue.Empty:
pass # 网页版的 qq
# sereve 端 djiong 写的
# 信息一直没有 一直夯在这 于是 用get_nowait() 没数据立刻返回
# 隔个0.5秒 再返回来查看 # 生产者 消费者 模型
# 达到效率平衡
# 一个生产数据和消费数据的完整的流程解耦解耦成两个部分:生产和消费
#由于生产速度和消费速度不一致,所以需要我们调整生产者和消费者额d个数来达到效率平衡
2.今日内容
#1 互斥锁
#2 进程之间的数据共享
#关于数据安全的问题
#3 进程池
#from multiprocessing import Pool
# 事件\信号量\管道
# 4 线程的概念(面试的重点)
# 5 认识线程模块
3.什么是互斥锁
# 在多个进程中 或者一个进程中
# 有acquire()acquire()就阻在那里了
#__author : 'liuyang'
#date : 2019/4/17 0017 上午 9:27
# from multiprocessing import Lock
# #1 互斥锁:不能在同一个进程内,‘也’有锁的竞争关系
# # 在同一个进程中连续acquire多次会产生死锁
# lock = Lock()
# lock.acquire() #拿走钥匙
# print(1)
# lock.acquire() #被拿走了又想要钥匙 卡住 #互斥
# print(2)
# # lock.release() #没还钥匙 卡在第一个开锁那
# lock.release()
# lock.release()
4.数据共享(进程内可以但是不大需要)
# 本来是数据隔离的
# 加上Manager就可以分享了
#__author : 'liuyang'
#date : 2019/4/17 0017 上午 9:35
#数据共享几乎不用
# 数据共享: 可以, Manager 但是不安全
# 可以 安全 加锁 from multiprocessing import Process,Manager,Lock
def func(dic):
dic['count'] -= 1 # 数据不共享 正常情况下数据隔离 子进程改
if __name__ == '__main__':
lock = Lock()
m = Manager()
dic = m.dict({'count':100})
p_l = []
for i in range(100):
p = Process(target=func,args=(dic,lock))
p.start()
p_l.append(p)
for p in p_l : p.join()
print(dic) #{'count': 0} 性能越好 越不得零 # 100 减 100次 1 这么慢? 不是减操作造成的
# 慢是因为 开100个进程 所以慢 开和管理 销毁进程拖慢了程序的运行效率 # 为什么在这里出现了数据不安全的现象?
# 正常不会数据共享 隔离 肯定通过socket 文本或者网络传过来的
# (不丢失)性能快的时候,比如两个 子进程同时对一样的值操作了,返回的一样的值 #什么情况会出现数据不安全:Manager 类当中对字典/列表 += -= *= /=
#添加值 不会
#如何解决 : 加锁 # 修改的 异步 性能高了会出错对同一个进行操作 #加锁同步安全
# 查看的 异步快 # cpu个数 最多起cpu*2个
#
5.多线程
cpython解释器内置的 GIL锁,同步
为了数据安全
解释性语言(一边解释一边编译 解释的字节码 无序 所以操作造成异步操作 数据不安全)
编译型语言可以实现多进程
#__author : 'liuyang'
#date : 2019/4/17 0017 上午 10:18
# 线程是进程中的一个单位
# 进程是计算机中最小的资源分配单位
# 线程是计算机中被CPU调度的最小单位 # 开启进程 关闭进程 切换进程都需要时间
# 你的电脑的资源还是优先的
# 开启过多的进程会导致你的计算机崩溃 # count_cpu*2 = 8 #4 核
# 同时对8个客户端服务
# qps 每秒的请求数 2W # 2000/8 = 250 台机器 # 进程: 数据隔离的
#ftp server端
#qq server端(不用隔离,本来就不传输,得写了才传)
# 并发: 同一时刻能同时接受多个客户端的请求
# 进程有大 有数据隔离 开多了还不行 (有的不需要隔离,还要ipc传输过来、) #线程:
# 轻型进程 轻量级的进程
# 在同一个进程中的多个线程是可以共享一部分数据的
# 线程的开启\销毁\切换都比进程要高级很多 #1.多个进程可不可以利用多核(多个CPU)
#2.多个线程可不可以利用多核(多个CPU)
# 都可以 # 多进程和多线程之间的区别
#进程 数据隔离 开销大 (必须数据隔离是才会进程)
#线程 数据共享 开销小 # python 当中的多线程
# Cpython 解释器 有一个GIL锁 (怕麻烦 要不太多修改的)
# # (解释性语言) 编译 --》字节码(bytes) 没法正常排序的-->机器码(0101)
# python 代码机器语言
from dis import dis
def func():
a = []
a.append(1)
dis(func)
'''
42 0 BUILD_LIST 0
2 STORE_FAST 0 (a) 43 4 LOAD_FAST 0 (a)
6 LOAD_ATTR 0 (append)
8 LOAD_CONST 1 (1) #加载他们几个存在内存里
10 CALL_FUNCTION 1 #调用
12 POP_TOP
14 LOAD_CONST 0 (None)
16 RETURN_VALUE''' #默认返回空
# 两个程序在两个cpu上同时触发,就可能造成数据不安全
# python 解释器(自动加锁) 同一时刻 只能有一个线程执行(单线程) # 解释性语言(python,php) 都不能多个程序(线程)访问多个cpu #(异步执行无序)所以数据不安全
# 编译型语言(c,java) 都能多个程序(线程)访问多个cpu # GIL 锁 历史遗留问题(python诞生时没有多核)
#线程中的状态 就不如编译型语言 那么完美 # python 当中的多线程(不是python的锅,可以解决的,没必要)
# 不能访问多个cpu
# 是Cpython(解决不了高运算) 解释器导致的 #不同的工具不同的功能
#每个工具都不是万能的
# GIL = 全局解释器锁 导致了同一时刻只能有一个线程访问cpu
# pypy 没有GIL锁 Jpython 解释成java 可以多线程访问多核的 (但是他们的执行效率慢) # 研究pypy(和cpython速度相近了) 不如直接研究 go
# go 的执行效率 和 c相近了 #利用 多核意味着 多个CPU可以同时计算线程中的代码 # IO 操作
#accept负责从网络上读取数据
#open() 调用操作系统的指令 0.9ms的时间 (cpu执行450万条指令(在阻塞))
#read #7个指令 一行代码 50w/7 7w条 python 代码 千分之一秒 执行的 # 分布式\多进程
#大量的计算 可以开 多进程 进多核 高额业务 # ftp 这样的大部分都是网络和进程都无关
# web 框架 #大部分时间 都是金阻塞 io呢 文件呢 网络呢 没大进cpu进行
#所以单进程多线程就够了
#Django flask tornado twistwed scrapy sanic
#都 并发 多线程 没有用进程 # 解释性和 编译型 的 因为一边翻译 一边编译 不如 直接汉语好 英语放过来
6.python代码实现 thread(进程)
#__author : 'liuyang'
#date : 2019/4/17 0017 上午 11:34
# 利 = 1
# 弊 = 2
# do = 'do'
# if 利 > 弊:
# do
#
import threading
# threading 和 multtiprocessing
# 先有的threading模块
#没有池的功能
#multiprocessing 完全模仿threading 模块完成的
#实现了池的功能
#concurrent.futures
#实现了线程池\进程池 # import os
# import time
# from threading import Thread
# def func(i): #子线程
# time.sleep(1) #阻塞了之后 cpu就绪 执行就不在控制范围内 了所以不按顺序
# print('in func',i, os.getpid())
#
# print('in main',os.getpid())
# #一个线程的时间开启和管理的时间不是固定的 开的时候有可能cpu很闲
# #直接执行了
#
# for i in range(20): #并发 #异步不是一起执行
# Thread(target=func,args=(i,)).start()
#func() #同步20 秒 20倍差别
#in main 4676
# in func 4676
# 在一个进程里 # if __name__ =='__main__': #多个线程都是 共享的 没有import没有导入
# 不会被执行 所以 不用
# 在线程部分不需要通过import来为新的线程获取代码
# 因为新的线程和之前的主线程共享同一段代码
# 不需要import 也就不存在 子进程中有重复了一次 # 开销 # 进程和线程的代码管理 是一样的 因为都是开和关 没必要有差距
# 数据隔离
#
# from multiprocessing import Process
# from threading import Thread
# import time
# def func(a):
# a += 1
# if __name__ =='__main__':
# start = time.time()
# t_l = []
#
# for i in range(100):
# t = Thread(target=func,args=(i,))
# t.start()
# t_l.append(t)
# for t in t_l : t.join() # 确保前面都执行完
# print('thread',time.time() - start )
#
# start = time.time()
# t_l = []
#
# for i in range(100):
# t = Process(target=func, args=(i,))
# t.start()
# t_l.append(t)
# for t in t_l: t.join() # 确保前面都执行完
# print('process',time.time() - start)
#
# #t 0.0870048999786377
# # p 7.8074469566345215
# 100倍 开进程倍 # 多个线程之间的全局变量是共享的
#
# from multiprocessing import Process
# from threading import Thread
# import time
# tn = 0
# def func(a):
# global tn
# tn += 1
# if __name__ =='__main__':
# start = time.time()
# t_l = []
#
# for i in range(100):
# t = Thread(target=func,args=(i,))
# t.start()
# t_l.append(t)
# for t in t_l : t.join() # 确保前面都执行完
# print('thread',time.time() - start )
# print(tn)
#
# # 进程之间数据隔离
# pn = 0 # 这里定义了 所以不报错
# def func(a):
# global pn
# pn += 1
#
# if __name__ == '__main__':
#
# start = time.time()
# t_l = []
#
# for i in range(100):
# t = Process(target=func, args=(i,))
# t.start()
# t_l.append(t)
# for t in t_l: t.join() # 确保前面都执行完
# print('process',time.time() - start)
# print(pn) # 线程中的几个替他方法
from threading import Thread,currentThread #线程对象
import os
def func():
t = currentThread() #线程属于哪个id的
print(t.name,t.ident,os.getpid())
# print(currentThread(),os.getpid()) tobj = Thread(target=func)
tobj.start()
print('tobj:',tobj)
# print(currentThread(),os.getpid())
'''
Thread-1 9224 9612
<_MainThread(MainThread, started 4108)> 9612
<Thread(Thread-1, started 9224)> 9612
'''
'''
Thread-1 8800 9588 #巧了 异步一样
tobj: <Thread(Thread-1, stopped 8800)>''' lst = [1,2,3,4,5,6,7,8,9,10]
#按照顺序把列表中的每一个元素都计算一个平方
#使用多线程方式
# #并且将结果按照顺序返回
from threading import Thread #线程对象
import time
import random
dic = {}
def func(i):
t = currentThread()
time.sleep(random.random())
dic[t.ident] = i**2
t_l = []
for i in range(1,11):
t = Thread(target=func, args=(i,))
t.start()
t_l.append(t)
for t in t_l:
t.join() # 确保前面都执行完
print(dic[t.ident])
print(dic) #{7936: 81, 6056: 4, 9344: 49, 10188: 9, 6648: 100, 7264: 64, 4072: 16, 9924: 36, 8796: 1, 7216: 25}
#这不是 按顺序添加的 只是显示是顺序的 添加是按顺序的 # from threading import active_count
# # 返回当前正在工作的线程
# from threading import Thread #线程对象
# import time
# import random
# l = []
# def func(a):
# t = currentThread()
# time.sleep(random.random())
# for i in range(1,11):
# t = Thread(target=func, args=(i,))
# #t.start() 11 个 不start() 就不执行
# print(active_count()) #1 #只有一个主线程 # 线程有terminate 么?
#没有terminate 不能强制结束
#所有的子线程都会在执行完所有的任务之后结束 # 统计线程的id 统计正在执行的线程数 用法差不多 没有terminate # 1 . 通读博客 :操作系统 ,进程,线程
# 2 . 把课上的代码都搞明白
# 3. 多线程实现一个并发 tcp协议的socket_server
# 4. 明天默写和线程相关的
day 34的更多相关文章
- mysql-5.6.34 Installation from Source code
Took me a while to suffer from the first successful souce code installation of mysql-5.6.34. Just pu ...
- CSharpGL(34)以从零编写一个KleinBottle渲染器为例学习如何使用CSharpGL
CSharpGL(34)以从零编写一个KleinBottle渲染器为例学习如何使用CSharpGL +BIT祝威+悄悄在此留下版了个权的信息说: 开始 本文用step by step的方式,讲述如何使 ...
- C#开发微信门户及应用(34)--微信裂变红包
在上篇随笔<C#开发微信门户及应用(33)--微信现金红包的封装及使用>介绍了普通现金红包的封装和使用,这种红包只能单独一次发给一个人,用户获取了红包就完成了,如果我们让用户收到红包后,可 ...
- 背水一战 Windows 10 (34) - 控件(进度类): RangeBase, Slider, ProgressBar, ProgressRing
[源码下载] 背水一战 Windows 10 (34) - 控件(进度类): RangeBase, Slider, ProgressBar, ProgressRing 作者:webabcd 介绍背水一 ...
- 基于Yahoo网站性能优化的34条军规及自己的见解
1.尽量减少HTTP请求次数 终端用户响应的时间中,有80%用于下载各项内容,这部分时间包括下载页面中的图像.样式表.脚本.Flash等.通过减少页面中的元素可以减少HTTP请求的次数,这是提高网页速 ...
- AC日记——回文子串 openjudge 1.7 34
34:回文子串 总时间限制: 1000ms 内存限制: 65536kB 描述 给定一个字符串,输出所有长度至少为2的回文子串. 回文子串即从左往右输出和从右往左输出结果是一样的字符串,比如:abb ...
- 34 网络相关函数(二)——live555源码阅读(四)网络
34 网络相关函数(二)——live555源码阅读(四)网络 34 网络相关函数(二)——live555源码阅读(四)网络 2)socketErr 套接口错误 3)groupsockPriv函数 4) ...
- Yahoo!网站性能最佳体验的34条黄金守则(转载)
1. 尽量减少HTTP请求次数 终端用户响应的时间中,有80%用于下载各项内容.这部分时间包括下载页面中的图像.样式表.脚本.Flash等.通过减少页面中的元素可以减少HTTP请求的次数 ...
- NYOJ题目34韩信点兵
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAskAAAHiCAIAAACV1MbSAAAgAElEQVR4nO3dPXLjONeG4W8TyrUQx1 ...
- Yahoo!网站性能最佳体验的34条黄金守则
Yahoo!的Exceptional Performance团队为改善Web性能带来最佳实践.他们为此进行了一系列的实验.开发了各种工具.写了大量的文章和博客并在各种会议上参与探讨.最佳实践的核心就是 ...
随机推荐
- 两个对象的 hashCode()或equals相同,equals或hashCode不一定相同--《案例演示》
两个对象的 hashCode()或equals相同,equals或hashCode不一定相同 1.两个对象的equals相同,hashCode不一定相同 在重写equals方法,未重写hashCode ...
- springboot的打包方式
先写一个测试接口 package com.example.demo; import org.springframework.web.bind.annotation.RequestMapping; im ...
- lamp之apache配置https访问
配置apache 使用https 注:怕其他人由于路径的原因出问题,首先声明一下,本人apache的安装目录为 : /usr/local/httpd2.4.25,如果不是,请参考进行配置 注: 对于如 ...
- linux centos 磁盘清理
执行df -h 与 du -sh / 所查询到的已用容量不对应 执行xfs_fsr来清理磁盘 参考 https://www.jianshu.com/p/0ded68808123
- Day08 - Ruby比一比:String的+=与concat串接
前情提要: 在第七天我们透过比较Symbol和String,发现字串比符号多了更多方法!为了活用string method,今天我们接续前文,来探讨一题跟字串有关的题目: Ruby经典面试题目#08( ...
- oracl遇到的问题
使用oracl数据库用 ALTER TABLE Students ADD CONSTRAINT PRINF_NAME_UNIQUE UNIQUE (sname) 添加唯一性约束,出现问题,报错为:a ...
- PHP : MySQLi【面向过程】操作数据库【 连接、建库、建表、增、删、改、查、关闭】
<?php /** *数据库操作关键函数 *mysql_connect:连接数据 *mysql_error:最后一次sql动作错误信息 *mysqli_query:执行sql语句,增删该查 *m ...
- Selenium+TestNG+Maven+Jenkins+SVN(转载)
转载自:https://blog.csdn.net/u014202301/article/details/72354069 一. 创建Maven项目,下载Selenium和TestNG的依赖(依赖可以 ...
- Commons Daemon procrun stdout initialized
参考 https://blog.csdn.net/qq_19865749/article/details/69664979 jvm路径错误
- hibernate NUMBER 精度
通过Hibernate映射实体时会根据数据库中NUMBER类型的精度,生成相应的POJO类中相对应的主键类型.经过亲测结果如下: NUMBER(1) POJO类中生成的是Boolean publicc ...