day33 网络编程之线程,并发以及selectors模块io多路复用
io多路复用
概要:
并发编程需要掌握的知识点:
开启进程/线程
生产者消费者模型!!!
GIL全局解释器锁(进程与线程的区别和应用场景)
进程池线程池 IO模型(理论) 1 多线程
线程的概念?
一个进程内默认就会有一个控制线程,该控制线程可以执行代码从而创建新的线程
该控制线程的执行周期就代表改进程的执行周期
线程VS进程
1、线程的创建开销小于进程,创建速度快
2、同一进程下的多个线程共享该进程的地址空间
GIL全局解释器锁
线程池
开启线程的两种方式:
from threading import Thread
from multiprocessing import Process
import time,os def task():
print('%s is running' % os.getpid())
time.sleep(5)
print('%s is done' % os.getpid()) class Mythread(Thread):
def __init__(self, name):
super().__init__()
self.name=name def run(self):
print('%s is running' % os.getpid())
time.sleep(5)
print('%s is done' % os.getpid()) if __name__ == '__main__':
# t=Thread(target=task,)
# t=Process(target=task,)
t=Mythread('xxxxx')
t.start() print('主')
'''
1、一个进程内不开子进程也不开“子线程”:主线程结束,该进程就结束 2、当一个进程内开启子进程时:
主线程结束,主进程要等,等所有子进程运行完毕,给儿子收尸 3、当一个进程内开启多个线程时:
主线程结束并不意味着进程结束,
进程的结束指的是该进程内所有的线程都运行完毕,才应该回收进程
'''
这里需要注意一下,在线程里不存在僵尸线程和孤儿线程的概念.
进程和线程的区别:
#瞅一眼:PPID,PID
from threading import Thread
from multiprocessing import Process
import time,os def task():
print('partent:%s self:%s' %(os.getppid(),os.getpid()))
time.sleep(5) if __name__ == '__main__':
t=Thread(target=task,)
# t=Process(target=task,)
t.start() print('主',os.getppid(),os.getpid()) #进程直接内存空间隔离
from threading import Thread
from multiprocessing import Process
import time,os n=100
def task():
global n
n=0 if __name__ == '__main__':
t=Process(target=task,)
t.start()
t.join() print('主',n) #线程之间内存空间共享
from threading import Thread
import time,os n=100
def task():
global n
n=0 if __name__ == '__main__':
t=Thread(target=task,)
t.start()
t.join() print('主',n)
线程的其他属性以及方法:
from threading import Thread,current_thread,enumerate,active_count
import time,os def task():
print('%s is running' %current_thread().getName())
time.sleep(5)
print('%s is done' %current_thread().getName()) if __name__ == '__main__':
# t=Thread(target=task,name='xxxx') # # 这里有其他的参数就接着往后传即可,没有就只写一个函数名
t=Thread(target=task)
t.start()
# print(t.name) #查看当前活着的线程
print(enumerate()[0].getName()) # # MainThread print(enumerate()[1].getName())------Thread-1
# 这里有两个进程所以索引值就是只有0,1,超出部分会报错,out of range
print(active_count())
print('主',current_thread().getName()) # # 主 MainThread
线程池:
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
from threading import current_thread
import time,random
def task(n):
print('%s is running' %current_thread().getName())
time.sleep(random.randint(1,3))
return n**2 if __name__ == '__main__':
# t=ProcessPoolExecutor() #默认是cpu的核数
# import os
# print(os.cpu_count()) t=ThreadPoolExecutor(3) #默认是cpu的核数*5
objs=[]
for i in range(10):
obj=t.submit(task,i)
objs.append(obj) t.shutdown(wait=True)
for obj in objs:
print(obj.result())
print('主',current_thread().getName())
这里有线程池的作业,我一并粘过来
# 默写的内容是爬虫线程池的回调机制的代码
# socket 套接字用线程池的方式去写,然后再用多线程的方式去写
# 文本处理工具的三个任务先把一个套接字写出来然后看看怎么改成线程的概念
'''
以下则是开启多线程的方式: from socket import *
from multiprocessing import Process
from threading import Thread
ser = socket(AF_INET, SOCK_DGRAM)
ser.bind(('127.0.0.1', 3020))
ser.listen(2)
def connunicate(conn):
while True:
data = conn.recv()
conn.send(data.upper()) if __name__ == '__main__':
while True:
conn, addr = ser.accept() t = Thread(target=connunicate, args=conn)
t.start()
''' '''
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
from threading import current_thread
import os
def task(n):
print('%s is running' % current_thread().getName()) if __name__ == '__main__':
t = ThreadProcessExecutor(12)
# t = ProcessPoolExecutor(4)
objs = []
for i in range(20):
obj = t.submit(task, i)
objs.append(obj) t.shutdown(wait=True)
for obj in objs:
print(obj.result())
print('主', os.getpid(), current_thread().getName())
''' # 线程池的版本要理解后背下来!*****
# 开启线程池的方式: 这里是中级版本,已经搞定,功能都实现了,想要的结果都得到了!
from socket import *
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
from threading import current_thread
import os server = socket(AF_INET, SOCK_STREAM)
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
server.bind(('127.0.0.1', 5038))
server.listen(3) def connunicate(conn,num):
while True:
data = conn.recv(1024)
conn.send(data.upper())
print(os.getpid())
conn.close() if __name__ == '__main__':
t = ThreadPoolExecutor(12)
objs = []
while True:
conn, addr = server.accept()
tt = t.submit(connunicate, conn, os.getpid())
objs.append(tt)
# t.shutdown(wait=True)
for ob in objs:
print(ob.result()) print('主', os.getpid()) # # 客户端版本如下:
# from socket import *
# import os
# client=socket(AF_INET,SOCK_STREAM)
# client.connect(('127.0.0.1', 5038))
#
# while True:
# msg=input('>>: ').strip()
# if not msg:continue
#
# client.send(msg.encode('utf-8'))
# print(os.getpid())
# data=client.recv(1024)
# print(data.decode('utf-8'))
以上的有需要补充的,那个文本操作没有写出来,把老师博客里面的代码粘过来,
from threading import Thread
msg_l=[]
format_l=[]
def talk():
while True:
msg=input('>>: ').strip()
if not msg:continue
msg_l.append(msg) def format_msg():
while True:
if msg_l:
res=msg_l.pop()
format_l.append(res.upper()) def save():
while True:
if format_l:
with open('db.txt','a',encoding='utf-8') as f:
res=format_l.pop()
f.write('%s\n' %res) if __name__ == '__main__':
t1=Thread(target=talk)
t2=Thread(target=format_msg)
t3=Thread(target=save)
t1.start()
t2.start()
t3.start()
其实也好理解,就是自己没有多想一想,过早的放弃了.
异步概念补充(含回调函数):
# #pip install requests
# import requests
# from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
# from threading import current_thread
# import time
# import os
#
# def get(url):
# print('%s GET %s' %(os.getpid(),url))
# response=requests.get(url)
# time.sleep(3)
# if response.status_code == 200:
# return {'url':url,'text':response.text}
#
# def parse(obj):
# res=obj.result()
# print('[%s] <%s> (%s)' % (os.getpid(), res['url'],len(res['text'])))
#
# if __name__ == '__main__':
# urls = [
# 'https://www.python.org',
# 'https://www.baidu.com',
# 'https://www.jd.com',
# 'https://www.tmall.com',
# ]
# # t=ThreadPoolExecutor(2)
# t=ProcessPoolExecutor(2)
# for url in urls:
# t.submit(get,url).add_done_callback(parse)
# t.shutdown(wait=True)
#
# print('主',os.getpid()) # '''
# 异步调用:
# 提交完任务(为该任务绑定一个回调函数),不用再原地等任务执行完毕拿到结果,可以直接提交下一个任务
# 一个任务一旦执行完毕就会自动触发回调函数的运行
#
# 回调函数的参数是单一的:
# 回调函数的参数就是它所绑定任务的返回值
#
# ''' #pip install requests import requests
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
from threading import current_thread
import time
import os def get(url):
print('%s GET %s' %(current_thread().getName(),url))
response=requests.get(url)
time.sleep(3)
if response.status_code == 200:
return {'url':url,'text':response.text} def parse(obj):
res=obj.result()
print('[%s] <%s> (%s)' % (current_thread().getName(), res['url'],len(res['text']))) if __name__ == '__main__':
urls = [
'https://www.python.org',
'https://www.baidu.com',
'https://www.jd.com',
'https://www.tmall.com',
]
t=ThreadPoolExecutor(2)
for url in urls:
t.submit(get,url).add_done_callback(parse)
t.shutdown(wait=True) print('主',os.getpid())
这里的异步概念是,默写的内容,已经默出来过的.
day33 网络编程之线程,并发以及selectors模块io多路复用的更多相关文章
- python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)
python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...
- python中网络编程之线程
网络编程之线程 什么是线程? 程序的执行线路.每个进程默认有一条线程.线程包含了程序的具体步骤. 多线程就是一个进程中有除主线程(默认线程)外还有多个线程. 线程与进程的关系(进程包含线程,而线程依赖 ...
- Java网络编程和NIO详解3:IO模型与Java网络编程模型
Java网络编程和NIO详解3:IO模型与Java网络编程模型 基本概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32 ...
- Python网络编程(线程通信、GIL、服务器模型)
什么是进程.进程的概念? 进程的概念主要有两点: 第一,进程是一个实体.每一个进程都有它自己的地址空间, 一般情况下,包括文本区域(text region).数据区域(data region)和堆栈( ...
- python成长之路【第十一篇】:网络编程之线程threading模块
一.threading模块介绍 threading 模块建立在 _thread 模块之上.thread 模块以低级.原始的方式来处理和控制线程,而 threading 模块通过对 thread 进行二 ...
- 8.6 day27 网络编程 osi七层协议 Time模块补充知识 TCP协议
Time模块补充知识 date和datetime区别是什么? date 就是年月日 datetime就是年月时时分秒 以下代码为什么会报错? import json from datetime imp ...
- 进程,线程,协程,io多路复用 总结
并发:要做到同时服务多个客户端,有三种技术 1. 进程并行,只能开到当前cpu个数的进程,但能用来处理计算型任务 ,开销最大 2. 如果并行不必要,那么可以考虑用线程并发,单位开销比进程小很多 线程: ...
- Python进程、线程、协程及IO多路复用
详情戳击下方链接 Python之进程.线程.协程 python之IO多路复用
- Python网络编程之线程,进程
一. 线程: 基本使用 线程锁 线程池 队列(生产者消费者模型) 二. 进程: 基本使用 进程锁 进程池 进程数据共享 三. 协程: gevent greenlet 四. 缓存: memcache ...
随机推荐
- which命令和bin目录
命令: which 作用: 查看执行命令所在位置 使用: which ls which useradd 等等... bin和sbin: 绝大多数可执行文件都保存在 /bin./sbin./usr/bi ...
- Python 三种过滤去重方法
SET集合去重 set(1,1,2) REDIS去重 布隆过滤器
- react轮播图----react-slick
1.安装 npm install react-slick; //安装样式 npm install slick carousel; 再在App.css中引入 @import "~slick-c ...
- 【转】Python学习路线
Python最佳学习路线图 python语言基础 (1)Python3入门,数据类型,字符串 (2)判断/循环语句,函数,命名空间,作用域 (3)类与对象,继承,多态 (4)tkinter界面编程 ( ...
- day02 编程语言和变量
编程语言 编程语言分为三种 机器语言:用计算机能听得懂的二进位制语言来写程序 汇编语言:用英文字母来代替二进位制来写的程序 高级语言(两种) 编译型语言(C语言):相当于谷歌翻译整个程序写好一次性写好 ...
- LeetCode(99):恢复二叉搜索树
Hard! 题目描述: 二叉搜索树中的两个节点被错误地交换. 请在不改变其结构的情况下,恢复这棵树. 示例 1: 输入: [1,3,null,null,2] 1 / 3 \ 2 输出 ...
- vue 的router的简易运用
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JMeter 如何把上一个请求的结果作为下一个请求的参数 —— 使用正则提取器
有这样一个压力测试环境,有一个上传页面,上传成功之后服务器会返回一些上传信息(比如文件的 id 或者保存路径之类的信息),然后压力机会继续下一个请求,比如调整 id 为 xx 的文件的一些信息等等.问 ...
- Django复习
django复习 django和其他框架的对比 django,集成很多功能的大型框架,为开发者提供了很多方便的组件:orm.form.ModelForm.auth.admin.contenttypes ...
- Sublime Text 3 快捷键总结(拿走)
以下是个人总结不完全的快捷键总汇,祝愿各位顺利解放自己的鼠标. 选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本. Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同 ...