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 ...
随机推荐
- Dubbo原理解析-Dubbo内核实现之SPI简单介绍
转自:https://blog.csdn.net/quhongwei_zhanqiu/article/details/41577159 Dubbo 采用微内核+插件体系,使得设计优雅,扩展性强.那所谓 ...
- 34)django-上传文件,图片预览功能实现
目录 文件上传 1)form表单提交上传(会刷新) 2)ajax上传 3)iframe 4)图片上传预览(思路保存文件的时候,把文件保存文件的路径反馈回,客户端 ...
- vue -webpack.dev.config.js模拟后台数据接口
在const portfinder = require('portfinder')后面添加 const express = require('express') const app = express ...
- C#操作excel(多种方法比较)
1.用查询表的方式查询并show在数据集控件上. public static string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; D ...
- Springboot 事务处理常见坑点
使用事务注解@Transactional 之前,应该先了解它的相关属性,避免在实际项目中踩中各种各样的坑点. 常见坑点1:遇到非检测异常时,事务不开启,也无法回滚. 例如下面这段代码,账户余额依旧增加 ...
- Confluence 6 后台中的选择站点首页
后台中的选择站点首页选择项. https://www.cwiki.us/display/CONFLUENCEWIKI/Configuring+the+Site+Home+Page
- <<人月神话>>阅读体会(一)
第一次听说人月神话还是在大一上学期的导论课那会儿,那会儿好像就已经确定了自己要学软件,于是就去问王建民老师能不能给我推荐几本软件工程方面的书,我想要提前自己学学,以为老师会给我推荐一些某种语言类的学习 ...
- SpringBoot定时任务
代码做定时任务:1.开个线程,线程里面休眠去做 2.使用一些定时任务的框架去做 1.创建TimerTest类 package com.cppdy.service; import org.springf ...
- LeetCode(88):合并两个有序数组
Easy! 题目描述: 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素 ...
- WEB测试总结
WEB测试总结:1.js文件session是否有缓存,如果没有缓存对服务器压力会很大:2.更改页面大小后,图表是否会再次向服务器请求数据:3.表单填写是否对html标识,script脚本做处理:(&l ...