io多路复用

selectors模块

概要:

 并发编程需要掌握的知识点:
开启进程/线程
生产者消费者模型!!!
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多路复用的更多相关文章

  1. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...

  2. python中网络编程之线程

    网络编程之线程 什么是线程? 程序的执行线路.每个进程默认有一条线程.线程包含了程序的具体步骤. 多线程就是一个进程中有除主线程(默认线程)外还有多个线程. 线程与进程的关系(进程包含线程,而线程依赖 ...

  3. Java网络编程和NIO详解3:IO模型与Java网络编程模型

    Java网络编程和NIO详解3:IO模型与Java网络编程模型 基本概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32 ...

  4. Python网络编程(线程通信、GIL、服务器模型)

    什么是进程.进程的概念? 进程的概念主要有两点: 第一,进程是一个实体.每一个进程都有它自己的地址空间, 一般情况下,包括文本区域(text region).数据区域(data region)和堆栈( ...

  5. python成长之路【第十一篇】:网络编程之线程threading模块

    一.threading模块介绍 threading 模块建立在 _thread 模块之上.thread 模块以低级.原始的方式来处理和控制线程,而 threading 模块通过对 thread 进行二 ...

  6. 8.6 day27 网络编程 osi七层协议 Time模块补充知识 TCP协议

    Time模块补充知识 date和datetime区别是什么? date 就是年月日 datetime就是年月时时分秒 以下代码为什么会报错? import json from datetime imp ...

  7. 进程,线程,协程,io多路复用 总结

    并发:要做到同时服务多个客户端,有三种技术 1. 进程并行,只能开到当前cpu个数的进程,但能用来处理计算型任务 ,开销最大 2. 如果并行不必要,那么可以考虑用线程并发,单位开销比进程小很多 线程: ...

  8. Python进程、线程、协程及IO多路复用

    详情戳击下方链接 Python之进程.线程.协程 python之IO多路复用

  9. Python网络编程之线程,进程

    一. 线程: 基本使用 线程锁 线程池 队列(生产者消费者模型) 二. 进程:  基本使用  进程锁 进程池 进程数据共享 三. 协程: gevent greenlet 四. 缓存: memcache ...

随机推荐

  1. 图解Metrics, tracing, and logging

    Logging,Metrics 和 Tracing   最近在看Gophercon大会PPT的时候无意中看到了关于Metrics,Tracing和Logging相关的一篇文章,凑巧这些我基本都接触过, ...

  2. LuoGu P1541 乌龟棋

    题目传送门 乌龟棋我并不知道他为啥是个绿题0.0 总之感觉思维含量确实不太高(虽然我弱DP)(毛多弱火,体大弱门,肥胖弱菊,骑士弱梯,入侵弱智,沙华弱Dp) 总之,设计出来状态这题就很简单了 设 f[ ...

  3. Confluence 6 修改默认空间标识图片

    空间标识图片在边栏上的站点目录(Sites Directory)中作为图标进行显示.默认的空间标识图片将会应用到所有的空间中,如果你没有自定义的空间标识被定义的话,请查看 Configure the ...

  4. vue install后出现的问题

    出现这个问题你要先把node-sass移除后重新安装 执行下面命令 npm remove node-sass --save-dev 然后安装 npm install node-sass@latest ...

  5. mongoDB基础使用

    环境交代 操作系统: CentOS 6.8 64位 mongodb: 4.06 安装 官方下载地址:https://www.mongodb.org/dl/linux/x86_64-rhel62 阿里云 ...

  6. python - 发送html格式的邮件

    import smtplibfrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextfrom ...

  7. 使用 declare 语句和strict_types 声明来启用严格模式:

    使用 declare 语句和strict_types 声明来启用严格模式: Caution: 启用严格模式同时也会影响返回值类型声明. Note: 严格类型适用于在启用严格模式的文件内的函数调用,而不 ...

  8. pyhon----函数和方法的关系

    1.如果使用类名调用,为函数,需要手动传self 2.如果使用对象调用,为方法,不用手动传self class Foo(object): def __init__(self): self.name=& ...

  9. Linux基础三:linux目录结构和目录文件的浏览、管理及维护

    目录文件的浏览.管理及维护(一) 1.Linux文件系统的层次结构 1)Linux文件系统的树状结构:在Linux或UNIX操作系统中,所有的文件和目录都被组织成一个以根节点开始的倒置的树状结构. 2 ...

  10. 多线程相关-ThreadPoolExecutor

    应用层面: ThreadPoolExecutor: 创建多线程池执行器:new ThreadPoolExecutor(),创建方法最终都是走的以下这个构造方法: /** * Creates a new ...