单核中,基本是时间片切换的去运行,肉眼和感觉是无法体会到的。
正在运行的程序
1、每个进程拥有自己的独立的地址空间,内存,数据栈,以及其他用于跟踪执行的辅助数据
2、各个进程之间相互独立,互不影响
import time
def new_time():
# 格式化时间输出
return time.asctime(time.localtime())
def func():
print('inner-start:',new_time())
time.sleep(5) # 模拟耗时操作
print('inner-end:',new_time())
func()
time.sleep(5)
print('outer',new_time())
import time
import multiprocessing
def new_time():
# 格式化时间输出
return time.asctime(time.localtime())
def func():
print('inner-start:',new_time())
time.sleep(5) # 模拟耗时操作
print('inner-end:',new_time())
print('outer--start',new_time())
p1 = multiprocessing.Process(target=func) # 实例化
p1.start() # 开启新的进程-子进程
time.sleep(5)
print('outer--end',new_time())
多进程
使用多进程来分担耗时任务,在另一个进程中运行耗时任务,这样主进程就不会收到影响。
当子进程执行完时,返回子进程的运行结果。
多进程
首先是multiprocessing.Process实例化,并且制定回调函数,参数列表。
实例化之后可以直接调用运行,这就实现了多进程运行,节省运行时间。
这里并行都只是Python层面的,并不是实际层面的。
当总进程数多于核心数的时候,多于的没有效果
多进程由操作系统调度运行。
轻量级进程
如果把进程比作一个工厂,那么线程就是工厂里面的工人,也就是一个进程可以包含多个线程
车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的,这象征一个进程的内存空间是共享的,每个进程都可以使用这些共享内存。
一个线程可以被抢占(中断)
也可以临时挂起(睡眠)
等。
线程的调度由Python解释器
调度,而进程由操作系统
调度
import time
import threading
def new_time():
return time.asctime(time.localtime())
def func(x):
print(x)
print('inner--start:',new_time())
time.sleep(5) # 模拟阻塞任务
print('inner--end:',new_time())
print('out--start',new_time())
t = threading.Thread(target=func,args=(1,)) # 实例化
t.start() # 开启新的线程
time.sleep(5)
print('outer--end',new_time())
模拟阻塞任务
多线程不适合解决计算密集型的情形,但是适合IO密集型的场景。因为在同一个进程内,并不会额外分配其他的系通资源。
Python中的多线程在遇到阻塞的时候,会自动切换到非阻塞的线程上去。
Python发明之初,还没有多核CPU的概念。为了利用多核,Python开始支持多线程。而解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁。于是有了GIL这把超级大锁
GIL锁要求,任何进程中,一次只能有一个线程在执行。因此,并不能为多个线程分配多个CPU。所以Python中的线程只能实现并发,而不能实现真正的并行。
Django Flask Web2py...
都是使用多线程来做
服务段代码
import socket
import multiprocessing
server = socket.socket()
server.bind(('127.0.0.1',8989))
server.listen(100)
def handle(connect):
'''处理数据请求'''
while True:
data_recv = connect.recv(1024)
if data_recv:
print(data_recv)
connect.send(data_recv)
else:
connect.close()
break
while True:
# 生成对等连接套接字
conn,addr = server.accept()
process = multiprocessing.Process(target=handle,args=(conn,))
process.start()
客户端代码
import socket
client = socket.socket()
client.connect(('127.0.0.1',8989))
for i in range(10):
client.send(b'hello')
print(client.recv(1024))
服务端代码
import socket
import threading
server = socket.socket()
server.bind(('127.0.0.1',8989))
server.listen(100)
def handle(connect):
while True:
data_recv = connect.recv(1024)
if data_recv:
print(data_recv)
connect.send(data_recv)
else:
connect.close()
break
while True:
conn,addr = server.accept()
th = threading.Thread(target=handle,args=(conn,))
th.start()
客户端代码
import socket
client = socket.socket()
client.connect(('127.0.0.1',8989))
for i in range(10):
client.send(b'hello')
print(client.recv(1024))