Python全栈最全学习之路-网络编程(三)

认识进程与线程

一、多任务深入理解

1、CPU时间片

Python全栈最全学习之路-网络编程(三)_第1张图片
单核中,基本是时间片切换的去运行,肉眼和感觉是无法体会到的。

2、进程的概念

Python全栈最全学习之路-网络编程(三)_第2张图片
正在运行的程序
1、每个进程拥有自己的独立的地址空间,内存,数据栈,以及其他用于跟踪执行的辅助数据
2、各个进程之间相互独立,互不影响

二、多进程实现

1、单一进程

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())

Python全栈最全学习之路-网络编程(三)_第3张图片
单一进程
使用睡眠来模拟耗时操作,查看这个程序的运行时间

2、开启多进程

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())


Python全栈最全学习之路-网络编程(三)_第4张图片
多进程
使用多进程来分担耗时任务,在另一个进程中运行耗时任务,这样主进程就不会收到影响。
当子进程执行完时,返回子进程的运行结果。

3、多进程

Python全栈最全学习之路-网络编程(三)_第5张图片
多进程
首先是multiprocessing.Process实例化,并且制定回调函数,参数列表。
实例化之后可以直接调用运行,这就实现了多进程运行,节省运行时间。
这里并行都只是Python层面的,并不是实际层面的。
当总进程数多于核心数的时候,多于的没有效果
多进程由操作系统调度运行。

三、多线程实现

1、线程概念

轻量级进程
如果把进程比作一个工厂,那么线程就是工厂里面的工人,也就是一个进程可以包含多个线程
车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的,这象征一个进程的内存空间是共享的,每个进程都可以使用这些共享内存。
一个线程可以被抢占(中断)也可以临时挂起(睡眠)等。
线程的调度由Python解释器调度,而进程由操作系统调度

2、代码实现

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())

    

Python全栈最全学习之路-网络编程(三)_第6张图片
模拟阻塞任务
多线程不适合解决计算密集型的情形,但是适合IO密集型的场景。因为在同一个进程内,并不会额外分配其他的系通资源。
Python中的多线程在遇到阻塞的时候,会自动切换到非阻塞的线程上去。

3、GIL全局解释锁

Python发明之初,还没有多核CPU的概念。为了利用多核,Python开始支持多线程。而解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁。于是有了GIL这把超级大锁
GIL锁要求,任何进程中,一次只能有一个线程在执行。因此,并不能为多个线程分配多个CPU。所以Python中的线程只能实现并发,而不能实现真正的并行。
Django Flask Web2py...都是使用多线程来做

四、并发服务器

1、多进程实现并发服务器

服务段代码

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))

2、多线程实现并发服务器

服务端代码

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))

你可能感兴趣的:(python全栈学习,python,多线程,网络,linux)