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. linux杀死僵尸进程

    用下面的命令找出僵死进程 ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]' 命令注解: -A 参数列出所有进程 -o 自定义输出字段 我们设定显示字段为 sta ...

  2. Fiddler 抓包工具

    序章 Fiddler是一个蛮好用的抓包工具,可以将网络传输发送与接受的数据包进行截获.重发.编辑.转存等操作.也可以用来检测网络安全.反正好处多多,举之不尽呀!当年学习的时候也蛮费劲,一些蛮实用隐藏的 ...

  3. OCP 相关课程列表

    OCP 相关课程列表 第一天:Linux基础 和 Oracle 11 R2 数据库安装教程图解 1:< VM 安装 linux Enterprise_R5_U4_Server_I386_DVD教 ...

  4. 关于npm 淘宝镜像 以及package.json里包的更新

    1.淘宝镜像的设置 npm config set registry https://registry.npm.taobao.org npm config set disturl https://npm ...

  5. Cookie禁用了,Session还能用吗?原因详解

    Cookie与 Session,一般认为是两个独立的东西,Session采用的是在服务器端保持状态的方案,而Cookie采用的是在客户端保持状态的方案.但为什么禁用Cookie就不能得到Session ...

  6. js----常用功能

    切割 1. a="ddd" a.substr(0,1) 通过js找子代 document.getElementByClass("ddd").getElement ...

  7. 数据库MySql的安装

    1.MySQL概述 MySQL最初是由“MySQL AB公司”开发的一套关系型数据库管理系统(RDBMS-Relation DataBase Management System).MySQL不仅是最流 ...

  8. 2017-2018-2 20165314 实验三《 敏捷开发与XP实践》实验报告

    知识点: 1.XP团队使用现场客户.特殊计划方法和持续测试来提供快速的反馈和全面的交流: -XP是以开发符合客户需要的软件为目标而产生的一种方法论 -XP是一种以实践为基础的软件工程过程和思想 -XP ...

  9. requests禁止重定向

    response = requests.get( 'http://weixin.sogou.com/weixin?query=%E9%A3%8E%E6%99%AF&type=2&pag ...

  10. 用JAVA写一个简单的英文加密器

    package qhs; import java.util.Scanner; public class JiaM { public static void main(String[] args) { ...