操作系统:向下控制硬件,向上支持软件运行
下载地址:Download PyCharm: Python IDE for Professional Developers by JetBrains
解压安装包:
切换到里面的bin目录,执行./pycharm.sh打开软件
多任务充分利用CPU资源,同时执行提高效率
并发:一段时间内交替执行多个任务(单核CPU处理多任务时)
并行:同时执行多个任务(多核CPU处理多任务)
进程:是操作系统进行资源分配和调度运行的最小单位
主进程:程序运行默认创建的进程
子进程:程序运行后创建的进程
导入进程包:import multiprocessing
通过进程类创建进程对象:进程对象=mutiprocessing.Process(target=任务名)
target参数指函数名,方法名。 name进程名一般不设置。group:进程组目前只能使用None
启动进程执行任务:进程对象.start()
代码如下:
import multiprocessing
import time
def coding():
for i in range(3):
print("Coding....")
time.sleep(0.2)
def music():
for i in range(3):
print("music...")
time.sleep(0.2)
if __name__ == '__main__':
coding_process = multiprocessing.Process(target=coding())
music_process = multiprocessing.Process(target=music())
coding_process.start()
music_process.start()
args传参时注意顺序一致,kwargs注意key与形参名相同
代码:
import multiprocessing
import time
def coding(num):
for i in range(num,name):
print(name)
print("Coding....")
time.sleep(0.2)
def music(count,name):
for i in range(3):
print(name)
print("music...")
time.sleep(count)
if __name__ == '__main__':
coding_process = multiprocessing.Process(target=coding, args=(4,"传智播客"))
music_process = multiprocessing.Process(target=music, kwargs={"count": 3,"name":"gyq"})
coding_process.start()
music_process.start()
引入os模块,getpid(),getppid()方法
import multiprocessing
import os
def work():
print("workid>>>%d" % os.getpid())
print("workpid>>>%d" % os.getppid())
if __name__ == '__main__':
print("pprocessid>>>%d" % os.getpid())
work_process = multiprocessing.Process(target=work)
work_process.start()
实际上是创建一个子进程就是把主进程资源进行拷贝产生了一个新的进程,两者相互独立
import multiprocessing
my_list = list()
def write():
for i in range(3):
my_list.append(i)
print("add:", i)
def read():
print(my_list)
if __name__ == '__main__':
write_process = multiprocessing.Process(target=write)
read_process = multiprocessing.Process(target=read)
write_process.start()
read_process.start()
import multiprocessing
import time
def work():
for i in range(10):
print("working..")
time.sleep(0.2)
if __name__ == '__main__':
work_process = multiprocessing.Process(target=work)
work_process.start()
time.sleep(1)
print("mainprocess over")
会打印主进程结束但是没有完全结束,哈哈~
主进程结束子进程也关闭的两种方法
1.设置为守护子进程,主进程结束子进程立马结束
2.手动结束
实现多任务的一个方法
进程一旦创建就会分配一定资源,像是两个人聊qq要打开两个qq软件一样
线程是程序执行的最小单位,进程只负责分配资源,而利用这些资源执行程序的是线程,也就是说进程是线程的容器,线程和与它同属一个进程的其他线程共享进程所拥有的全部资源,像是qq的两个聊天窗口。
在进程中默认有一个线程执行程序,称为主线程
和进程类似
执行带参数的任务的方法与进程相同
import time
import threading
def coding():
for i in range(3):
print("coding...")
time.sleep(0.2)
def music():
for i in range(3):
print("music..")
time.sleep(0.2)
if __name__ == '__main__':
coding_thread = threading.Thread(target=coding)
music_thread = threading.Thread(target=music)
coding_thread.start()
music_thread.start()
主线程会等待所有子线程执行结束后主线在结束,设置守护子线程与进程方式相同
是无序的,由CPU调度
import threading
def get_info():
current_thread = threading.current_thread()
print(current_thread)
if __name__ == '__main__':
for i in range(10):
sub_thread = threading.Thread(target=get_info)
sub_thread.start()
import threading
import time
my_list = []
def write():
for i in range(3):
print("add:", i)
my_list.append(i)
print("write:", my_list)
def read():
print("read:", my_list)
if __name__ == '__main__':
write_thread = threading.Thread(target=write)
read_thread = threading.Thread(target=read)
write_thread.start()
time.sleep(1)
read_thread.start()
import threading
import time
g_num=0
def add1():
for i in range(100000):
global g_num
g_num+=1
print("g_num:", g_num)
def add2():
for i in range(100000):
global g_num
g_num+=1
print("g_num2:", g_num)
if __name__ == '__main__':
add1_thread = threading.Thread(target=add1)
add2_thread = threading.Thread(target=add2)
add1_thread.start()
add2_thread.start()
实现线程同步:
互斥锁:对共享数据进行锁定,保证同一时刻只有一个线程操作
创建互斥锁和上锁,解锁
不释放锁就会死锁,别的线程无法访问数据,卡死 记得释放锁
线程依附与进程
一个进程默认提供一条线程,进程可以创建多个线程
区别:
进程之间不共享全局变量
线程之间共享全局变量,但要注意资源竞争的问题
创建进程的资源开销比创建线程的资源开销要大
进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位
线程不能独自运行
优点:可以使用多核
缺点:资源开销大
优点:资源开销小
缺点:不能使用多核
实现资源共享和信息传递的虚拟平台
网络编程:编写基于网络通信的软件和程序
每个网络软件都有一个端口,端口有其对应端口号
知名端口号:0到1023,一般固定分配给一些服务,比如21端口分配给FTP服务,25端口是SMTP
服务,80端口分给HTTP服务。
动态端口号:1024到65535,如果没有设置就会随机生成一个,使用完后释放
简称套接字,是程序间进行网络通讯的工具
Transmission Control Protocol传输控制协议,面向连接的,可靠的,基于字节流的传输层协议。
面向连接:通信双方必须先建立好连接才能进行数据的传输,双方都会为此连接分配必要资源来记录连接的状态和信息,数据传输完成后,双方必须断开连接,以释放系统资源。
可靠:
采用发送应答机制,发送后得到应答才认为发送成功
超时重传:发送一个报文后启动定时器,指定时间内没有得到应答就会重新发送这个报文段
错误校验:TCP用一个校验和函数来校验数据是否有误,再发送和接收时都要计算校验和
流量控制和拥塞控制:流量控制用来避免发送端发送过而导致对方来不及接收
过程:创建连接,传输数据,关闭连接
网络传输以二进制进行传输
encode,decode函数(encoding='utf-8')
网络应用程序分为客户端和服务端,主动发起建立连接的是客户端
流程:
创建客户端套接字对象
和服务端套接字建立连接
发送数据
接收数据
关闭客户端套接字
案例:
import socket
if __name__ == '__main__':
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# AF_INET:ipv4,SOCK_STREAM:TCP
tcp_client_socket.connect(("111.111.111.111", 8080))
# tuple("ipaddress",port)
tcp_client_socket.send('are you ok?'.encode(encoding='utf-8'))
recv_data = tcp_client_socket.recv(1024)
print(recv_data.decode())
tcp_client_socket.close()
流程:
创建服务气短套接字对象
绑定IP地址和端口号
设置监听
等待接受客户端请求
接收数据
发送数据
关闭套接字对象
代码:
import socket
if __name__ == '__main__':
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.bind(('192.168.199.131', 8888))
# ''=localhost
tcp_server_socket.listen(128) # 128 means max wait num 只接收
conn_socket, ip_port = tcp_server_socket.accept()#返回一个用以和客户端通讯的socket和客户端地址
print('address', ip_port)
recv_data = conn_socket.recv(1024)
print("getinformation:", recv_data.decode())
conn_socket.send("get it already!".encode())
conn_socket.close()
tcp_server_socket.close()
运行客户端时服务器端输出
客户端输出
加一个while True即可完成多个客户端与其通信
用线程真正的同时服务于客户端:
import socket
import threading
def handle_client(conn_socket):
recv_data = conn_socket.recv(1024)
print("getinformation:", recv_data.decode())
conn_socket.send("get it already!".encode())
conn_socket.close()
if __name__ == '__main__':
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.bind(('192.168.199.131', 8888))
# ''=localhost
tcp_server_socket.listen(128) # 128 means max wait num
while True:
conn_socket, ip_port = tcp_server_socket.accept()
print('address', ip_port)
sub_thread = threading.Thread(target=handle_client, args=(conn_socket,))
sub_thread.start()
tcp_server_socket.close()
cd 到包含静态资源的static文件夹