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. select+异步

    IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程.IO多路复用适用如下场合: 当客户处理多个描述符时(一般是交互式输入和网络套接口),必须使用I/O复用. 当一个客户 ...

  2. Linux学习之CentOS(二)--初识linux的一些常用命令

    Linux学习之CentOS(二)--初识linux的一些常用命令 在VM上安装完了CentOS6.4以后,看着linux系统成功跑起来,心里小激动了一把......但是前方学习的道路还很遥远... ...

  3. Confluence 6 H2 数据库连接与合并整合

    使用 H2 console 连接到你嵌入的 H2 数据库 可以选的,你可以使用 H2 console 来连接到你的 H2 数据库.最简单的访问 Console 的方法是双击 H2 数据库的 jar 文 ...

  4. selenium之 chromedriver与chrome版本映射表(更新至v2.33)

    看到网上基本没有最新的chromedriver与chrome的对应关系表,便兴起整理了一份如下,希望对大家有用: chromedriver版本 支持的Chrome版本 v2.33 v60-62 v2. ...

  5. ob_start用法详解

    用PHP的ob_start(); 一. 相关函数简介:1.Flush:刷新缓冲区的内容,输出.函数格式:flush()说明:这个函数经常使用,效率很高.2.ob_start :打开输出缓冲区函数格式: ...

  6. 用gojs写的流程图demo

    领导要求,可以展开收缩子级,但是子级可以有多个父级,一开始用的dagre-d3.js,但是功能不是太全,无意中看到gojs,感觉还不错,所以拿来改了改... 代码地址:https://github.c ...

  7. WireShark Wifi认证数据包分析(论文idea)

    1.使用 wireShark捕获802.11数据帧结构分成三种,管理帧.控制帧.数据帧. 使用的过滤语法: 过滤MAC 地址: Waln.bssid eq=8c:23:0c:44:21:0f 过滤特定 ...

  8. java概念基础笔记整理

    1.构造方法没有类型,有类型的不是不叫构造方法. 2.一个类的的成员变量可以是java允许的任何数据类型,一个类可以把某个对象作为自己的一个成员变量,如果用这样的类创建对象,那么该对象中就会其他对象, ...

  9. java web----URL

     简单使用 import java.io.*; import java.net.HttpURLConnection; import java.net.MalformedURLException; im ...

  10. 通过iostat来查看linux硬盘IO性能|实例分析

    iostat查看linux硬盘IO性能 rrqm/s: 每秒进行 merge 的读操作数目.即 delta(rmerge)/s wrqm/s: 每秒进行 merge 的写操作数目.即 delta(wm ...