a、进程特征
* 进程是操作系统资源分配的最小单位
* 每个进程单独占有4G虚拟内存
* 进程之间相互独立,运行互不影响
b、线程特征
* 线程是计算机核心分配的最小单位
* 一个进程可以包含多个线程
* 线程也是一个运行过程,也要消耗计算机资源。多个线程共享其进程的资源和空间
* 线程也拥有自己特有的资源属性,比如指令集,TID等
* 线程无论创建还是删除还是运行资源消耗都小于进程
* 多个线程之间并行执行,互不干扰
* 两者都是多任务编程的方式,都能够使用计算机多核资源
* 进程创建和删除要比线程消耗更多计算机资源
* 进程空间独立数据安全性好,有专门的通信方法
* 线程使用全局变量通信,更加简单,但是往往需要同步互斥操作
* 一个进程可以包含多个线程,线程共享进程资源
* 进程、线程都有自己的特有属性资源,如命令、id等
线程使用场景:
如果需要创建较多的并发,任务比较简单,线程比较适合
如果数据操作和功能比较独立,此时使用进程比较合适
使用线程时需要考虑到同步互斥复杂程度
python线程要考虑到GIL问题
池的使用场景:
线程池应用较少,用的最多的是进程池。
解决对共有资源操作产生的争夺
临界资源 :多个进程或者线程都能够操作的资源
临界区:操作临界资源的代码段
同步:是一种合作关系,为完成某个任务,多进程或者多线程之间形成一种协调。按照约定依次执行对临界资源的操作,相互告知相互促进。
互斥:互斥是一种制约关系,当一个进程占有临界资源就会进行加锁的操作,此时其他进程就无法操作该临界资源。知道使用的进程进行解锁操作后才能使用。
from multiprocessing import Event
创建事件对象
e = Event()
事件阻塞
e.wait([timeout])
事件设置
e.set()
功能 : 当e被set() 后 e.wait()不再阻塞
事件清除
e.clear()
功能 : 当e被clear()后 e.wait()又会阻塞
事件判断 判断当前事件对象是否被设置
e.is_set()
from multiprocessing import Lock
创建对象
lock = Lock()
lock.acquire() 上锁
lock.release() 解锁
上锁状态 : 执行acquire()操作会阻塞
解锁状态 : 执行acquire()不阻塞
with lock: ---> 上锁
...
...
----》 with代码段结束即解锁
* 在lock对象处于上锁状态的时候,再企图上锁则会阻塞,直到锁被释放,才能继续执行上锁操作
线程的资源访问,除了可以通过同步互斥机制来确保数据的安全一致性,也可以通过全局变量进行限制。
import threading
e = threading.Event()
e.wait([timeout]) 如果e为设置状态则不阻塞,未设置则阻塞
e.set() 将e变为设置状态
e.clear() 将e设置去除
import threading
lock = threading.Lock() 创建锁
lock.acquire() 上锁
lock.release() 解锁
操作原理 : 重复上锁 acquire()会阻塞
import threading
创建条件变量对象
con = threading.Condition()
con.acquire() : 对资源加锁,加锁后其他位置再加锁则阻塞
con.release() : 解锁
con.wait() : wait函数只能在 加锁的状态下使用。 wait函数会先解锁(release),然后让线程处于等待通知的阻塞状态
con.notify() : 发送通知,线程接收到通知后 结束wait阻塞,并且执行 acquire 加锁操作
from multiprocessing import Event,Process
from time import sleep
'''
三个进程都要操作共享资源
要求必须主进程先操作
子进程中谁先操作都可以,但是有一个子进程不能长期阻塞
'''
def wait_event():
print("process1也想操作临界区,但是要阻塞等待主进程")
e.wait()
print("主进程操作完了,轮到我了",e.is_set())
def wait_event_timeout():
print("process2也想操作临界区,但是要阻塞等待主进程")
e.wait(2)
print("我等不了了,还是执行别的吧",e.is_set())
e = Event()
p1 = Process(name = 'block',target = wait_event)
p2 = Process(name = 'non-block',\
target = wait_event_timeout)
p1.start()
p2.start()
print("假设正在忙碌的操作临界资源")
sleep(3)
e.set()
print("主进程操作完了,开放临界区")
p1.join()
p2.join()
from multiprocessing import Process,Lock
import sys
from time import sleep
#sys.stdout为共享资源,所有进程都可以操作
def worker1():
lock.acquire() #上锁
for i in range(5):
sleep(1)
sys.stdout.write("worker1 输出\n")
lock.release() #解锁
def worker2():
#with方式上锁
with lock:
for i in range(5):
sleep(1)
sys.stdout.write("worker2 输出\n")
#创建Lock对象
lock = Lock()
w1 = Process(target = worker1)
w2 = Process(target = worker2)
w1.start()
w2.start()
w1.join()
w2.join()
from threading import Thread
from time import sleep
#通过全局变量进行线程通信
a = 1
def foo():
global a
a = 1000
def bar():
sleep(1)
print("a =",a) # a = 1000
t1 = Thread(target = foo)
t2 = Thread(target = bar)
t1.start()
t2.start()
t1.join()
t2.join()
import threading
from time import sleep
s = None
#创建事件对象
e = threading.Event()
def bar():
print("呼叫foo")
global s
s = "天王盖地虎"
def foo():
print("等待口令")
sleep(2)
if s == "天王盖地虎":
print("自己人")
else:
print("打死他")
e.set()
def fun():
print("呵呵....")
sleep(1)
e.wait()
global s
s = "小鸡炖蘑菇"
t1 = threading.Thread(target = bar)
t2 = threading.Thread(target = foo)
t3 = threading.Thread(target = fun)
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
import threading
a = b = 0
lock = threading.Lock()
def value():
while True:
lock.acquire()
if a != b:
print("a = %d,b = %d"%(a,b))
lock.release()
t = threading.Thread(target = value)
t.start()
while True:
lock.acquire()
a += 1
b += 1
lock.release()
t.join()
import threading
import time
import datetime
num = 0
#条件变量
con = threading.Condition()
class Gov(threading.Thread):
def run(self):
global num
con.acquire()
while True:
print("开始拉升股市")
num += 1
print("拉升到 %d 个点"%num)
time.sleep(2)
if num == 5:
print('暂时安全!')
con.notify()
print("不操作状态")
con.wait()
con.release()
class Consumers(threading.Thread):
def run(self):
global num
con.acquire()
while True:
if num > 0:
print("开始打压股市")
num -= 1
print("下降到%d个点"%num)
time.sleep(2)
if num == 0:
print("天台在哪")
con.notify()
print("不能在下降了")
con.wait()
con.release()
t1 = Gov()
t2 = Consumers()
t1.start()
t2.start()
python2 SocketServer
python3 socketserver
功能:通过模块的接口完成基于多进程/多线程的tcp/udp的socket并发程序
意思 | 等同效果 | |
StreamRequestHandler | 处理tcp请求 | |
DatagramRequestHandler | 处理udp请求 | |
ForkingMixIn | 建立多进程 | |
ForkingTCPServer | 建立多进程tcp server | ForkingMixIn + TCPServer |
ForkingUDPServer | 建立多进程udp server | ForkingMixIn + UDPServer |
ThreadingMixIn | 建立多线程 | |
ThreadingTCPServer | 建立多线程tcp server | ThreadingMixIn + TCPServer |
ThreadingUDPServer | 建立多线程udp server | ThreadingMixIn + UDPServer |
TCPServer | 建立tcp server | |
UDPServer | 建立udp server |
from socketserver import *
#多进程tcp并发
#创建指定类型的服务器
# class Server(ForkingMixIn,TCPServer):
class Server(ForkingTCPServer):
pass
#处理具体请求
class Handler(StreamRequestHandler):
def handle(self):
#self.request 相当于accept 返回的套接字
print("Connect from",\
self.request.getpeername())
while True:
data = self.request.recv(1024).decode()
if not data:
break
print(data)
self.request.send(b"Receive your message")
#生成服务器对象
server = Server(('0.0.0.0',9999),Handler)
#启动服务器
server.serve_forever()
from socketserver import *
#多进程udp并发
class Server(ForkingUDPServer):
pass
class Handler(DatagramRequestHandler):
def handle(self):
#接受消息
while True:
data = self.rfile.readline().decode()
if not data:
break
print(data)
self.wfile.write(b'Receive message')
server = Server(("0.0.0.0",8888),Handler)
server.serve_forever()
人工智能(PythonNet)—— 目录汇总