网络编程:
1, 操作系统 / 应用程序
a, 硬件
- 硬盘
- CPU
- 主板
- 显卡
- 内存
- 电源
...
b.系统(软件)
- 系统就是一个程序员写出来的软件, 该软件用于控制计算机的硬件, 让他们之间进行相互配合
c, 装软件(安装应用程序)
- python
- pytharm
- 软件基于操作系统
2, 并发和并行
并发, 伪, 由于执行速度特别快, 人感觉不到停顿.
并行, 真,创建10个人同时操作.
3, 线程, 进程:
线程:
工作的最小单元
共享继承中所有的资源
每个线程可以分担一些任务, 最总完成最后的结果.
进程:
独立开辟内存
进程之间的数据隔离
线程与线程之间默认非常难通信, 如果需要通信需要特殊的方法.
a, 单进程, 单线程的应用程序
print(666)
b, 到底什么是线程?什么是进程?
python自己是没有的,
c, 单线程, 多进程的应用程序:
import threading print(666) def func(arg): print(arg) t = threading.Thread(target=func) t.start() print('end')
一个应用程序(软件), 可以有多个进程(默认只有一个), 一个进程中可以创建多个线程(默认一个)
总结:
1, 操作系统帮助开发者操作硬件
2, 程序员写好代码在操作系统上运行(以来解释器).
任务特别多
3, 以前的你写代码:
串行:
import requests import uuid url_list = [ 'https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg', 'https://www2.autoimg.cn/newsdfs/g28/M09/FC/06/120x90_0_autohomecar__ChcCR1uQlD6AT4P3AAGRMJX7834274.jpg', 'https://www2.autoimg.cn/newsdfs/g3/M00/C6/A9/120x90_0_autohomecar__ChsEkVuPsdqAQz3zAAEYvWuAspI061.jpg', ] def task(url): """""" """ 1. DNS解析,根据域名解析出IP 2. 创建socket客户端 sk = socket.socket() 3. 向服务端发起连接请求 sk.connect() 4. 发送数据(我要图片) sk.send(...) 5. 接收数据 sk.recv(8096) 接收到数据后写入文件。 """ ret = requests.get(url) file_name = str(uuid.uuid4()) + '.jpg' with open(file_name, mode='wb') as f: f.write(ret.content) for url in url_list: rask() ''' - 你写好代码 - 交给解释器运行,python111.pytharm - 解释器读取代码,再交给操作系统执行,根据你的代码去选择创建多少个线程进程去执行(单进程/单线程) - 操作系统条用硬件:硬盘,CPU... '''
4, 现在的你写代码:
a: import threading import requests import uuid url_list = [ 'https://www3.autoimg.cn/newsdfs/g28/M05/F9/98/120x90_0_autohomecar__ChsEnluQmUmARAhAAAFES6mpmTM281.jpg', 'https://www2.autoimg.cn/newsdfs/g28/M09/FC/06/120x90_0_autohomecar__ChcCR1uQlD6AT4P3AAGRMJX7834274.jpg', 'https://www2.autoimg.cn/newsdfs/g3/M00/C6/A9/120x90_0_autohomecar__ChsEkVuPsdqAQz3zAAEYvWuAspI061.jpg', ] def task(url): """""" """ 1. DNS解析,根据域名解析出IP 2. 创建socket客户端 sk = socket.socket() 3. 向服务端发起连接请求 sk.connect() 4. 发送数据(我要图片) sk.send(...) 5. 接收数据 sk.recv(8096) 接收到数据后写入文件。 """ ret = requests.get(url) file_name = str(uuid.uuid4()) + '.jpg' with open(file_name, mode='wb') as f: f.write(ret.content) for url in url_list: t = threading.Thread(target=task, args=(url,)) t.start() ''' - 你写好代码 - 交给解释器运行,python111.pytharm - 解释器读取代码,再交给操作系统执行,根据你的代码去选择创建多少个线程进程去执行(单进程/4线程) - 操作系统条用硬件:硬盘,CPU... '''
python多线程的情况下:
- 计算密集型操作: 效率低.(GIL锁)
- IO操作: 效率高
python多进程的情况下:
- 计算密集型操作: 效率高(浪费资源), 不得已而为之.
- IO操作: 效率高
以后写python时:
IO密集型用多线程: IO / 输入输出 / socket网络通信
计算密集型用多进程: 以外都是
扩展:
java多线程的情况下:
- 计算密集型操作: 效率高.
- IO操作: 效率高
java多进程的情况下:
- 计算密集型操作: 效率高(浪费资源)
- IO操作: 效率高, (浪费资源)
4, GIL锁, 全局解释器锁:
限制一个进程中有同一个时刻只有一个线程被CPU被调用
扩展:
默认GIL锁在执行100个CUP指令.才会切换执行的线程(过期时间)
5, 线程编写:
import threading def func(arg): print(arg) t = threading.Thread(target=func, args=(11,)) t.start() print(123)
# 主线程默认等子线程执行完毕
import time def fun(arg): time.sleep(1) print(arg) t1 = threading.Thread(target=fun, args=(11,)) t1.start() t2 = threading.Thread(target=fun, args=(11,)) t2.start() print(123)
# 主线程不在等子线程,主线程终止则子线程终止
import time def fun(arg): time.sleep(1) with open('a.py', 'wb') as f: f.write(b'as_das') print(1) t1 = threading.Thread(target=fun, args=(11,)) t1.setDaemon(True) t1.start() t2 = threading.Thread(target=fun, args=(11,)) t2.setDaemon(True) t2.start() print(123)
# 开发者可以控制主线程等待子线程(最多等待时间)
import time def fun(arg): time.sleep(1) with open('a.py', 'wb') as f: f.write(b'as_das') print(1) print('穿件子线程1') t1 = threading.Thread(target=fun, args=(11,)) t1.setDaemon(True) t1.start() t1.join(1) # 无参数:让主线程在这等着,等到子线程1执行完毕才可以继续往下走 # 有参数:让主线程在这最多等待N秒,无论是否执行完毕,会继续往下走. print('穿件子线程2') t2 = threading.Thread(target=fun, args=(11,)) t2.setDaemon(True) t2.start() t2.join(1) # 让主线程在这等着,等到子线程2执行完毕才可以继续往下走 print(33)
# 线程的名称
def fun(arg): # 获取当前执行该函数的线程的名称 n1 = threading.current_thread() # 根据当前线程对象获取当前线程名称 n2 = n1.getName() print(n2, arg) t1 = threading.Thread(target=fun, args=(11,)) t1.setName('厚哦') t1.start() t2 = threading.Thread(target=fun, args=(22,)) t1.setName('薄哦') t2.start() print(33)
# 线程的本质
def func(arg): print(arg) t1 = threading.Thread(target=func, args=(11,)) t1.start() # start 是开始运行线程么? 不是的 # start 告诉CUP,我已经准备就续,你可以调度我了. print(33)
# 补充面向对象版本的线程
# 多线程方式:1
def fun(arg): print(arg) t1 = threading.Thread(target=fun, args=(11,)) t1.start()
# 面向对象创建多线程:
class MyThread(threading.Thread): def run(self): print(111, self._args) t1 = MyThread(args=(11,)) t1.start()
6, 总结:
1, 应用程序 / 进程 / 线程的关系? ** ** *
2, 为什么要创建线程?
-由于线程是CPU工作的最小单元, 创建线程可以利用多核优势实现并行操作(java, c
# )
3, 为什么要创建进程?
进程和进程之间做数据隔离(java / c
# )
注意: 进程是为了提供环境让线程工作
4, python
a, python中存在一个GIL锁. ** ** *
- 造成: 多线程无法利用多核优势.
- 解决方案:开多进程处理(浪费资源)
总结:
IO密集型:多线程
计算密集型: 多进程
b, 线程的创建:
- Thread ** ** *
- MyThread
c, 其他 ** ** *
-join
- setDeanon
- setName
- htreading.current_thread()
d, GIL锁
- 获得
- 释放
小甜点:
-OSI 7层模型
-三次握手四次挥手
-其他网络知识
- mac
- IP
- 子网掩码
- 网关
- DHCP服务
- 路由器
- 交换机
- 广播/单播
- arp协议
- DNS
-补充
- 私有云/公有云
- 租服务器/域名