前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

进程通信

队列(Queue)
from multiprocessing import Queue
q = Queue() # 创建队列 该队列为子进程共享,为跨进程通信队列
q.get(block=True) # 阻塞从队列拿取一条数据,并从队列中去除,取不到时会阻塞等待
q.get_nowait() # 非阻塞形式获取队列中的数据
q.put() # 阻塞向队列放一条数据,当队列满了之后会阻塞等待
q.put_nowait() # 非阻塞向队列存放数据,队列满了直接报错
q.empty() # 判断队列是否为空
q.full() # 判断队列是否已满
q.qsize() # 返回当前队列中数据个数
  • 参考代码
from multiprocessing import Queue,Process,current_process
import time
def work(q):
    while True:
    	time.sleep(0.5)
        try:
        	num = q.get(False)
        	print(current_process().name,':',num)
        except:
          	break
def main():
    q = Queue()
    for var in range(5):
      	q.put(var)
    p = Process(target=work,args=(q,))
    p1 = Process(target=work,args=(q,))
    p.start()
    p1.start()
    p1.join()
    p.join()
if __name__ == '__main__':
	main()
管道(Pipe)

pipe意为管道,默认的为全双工,同时可以接收发送

from multiprocessing import Pipe
parent_pipe,child_pipe = Pipe(duplex=True) # 初始化管道

child_pipe|parent_pipe.recv() # 接收管道另一侧发来的消息
child_pipe|parent_pipe.send() # 向管道另一侧发送一条消息
child_pipe|parent_pipe.close() # 关闭管道
  • 注意:接收和发送必须是pickle处理后的序列化对象
管道实现的生产者消费者模型

生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题

生产者和消费者彼此之间不直接通讯,而通过队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给队列,消费者不找生产者要数据,而是直接从队列里取

队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

from multiprocessing import current_process,Pipe,Process,Lock
import pickle
import time
def pro(conn_pipe): #生产者
    for var in range(5):
        print(current_process().name)
        pick_obj = pickle.dumps('abcd')
        conn_pipe.send(pick_obj)
        
def cus(conn_pipe): #消费者
    var = pickle.loads(conn_pipe.recv())
    print(current_process().name,':',var)
    
def main():
    a,b = Pipe()
    p1 = Process(target=pro,args=(a,),name='生产者')
    work_list = []
    for var in range(5):
      	work_list.append(Process(target=cus,args=(b,),name='消费者%d' % var))
    p1.start()
    for work in work_list:
      	work.start()
    p1.join()
    for work in work_list:
      	work.join()
if __name__ == '__main__':
	main()
状态通信(Event)

Event类似状态通信,进程之间可以通过判断Event状态来执行工作

from multiprocessing import Event
e = Event()

e.wait() # 当实例状态为False时阻塞执行	
e.clear() # 状态设置为False
e.set() # 状态设置为True
  • 该种通信方式一般用在控制子进程业务执行顺序
from multiprocessing import current_process,Process,Lock,Event
import time
import sys
def work(e):
    print("我是进程:%s 我正在等待Event信号." % current_process().name)
    sys.stdout.flush()
    e.wait()
    print("我是进程:%s 我等待到了Event信号." % current_process().name)

def main():
    e = Event()
    p = Process(target=work,args=(e,))
    p.start()
    print("work进程开始工作")
    time.sleep(3)
    e.set()
    p.join()

if __name__ == '__main__':
	main()
共享内存(Array,Value)
  • 共享内存可选类型选项
'b' signed char int 1   
'B' unsigned char int 1   
'u' Py_UNICODE Unicode character 2 (1) 
'h' signed short int 2   
'H' unsigned short int 2   
'i' signed int int 2   
'I' unsigned int int 2   
'l' signed long int 4   
'L' unsigned long int 4   
'q' signed long long int 8 (2)  	
'Q' unsigned long long int 8 (2) 
'f' float float 4   
'd' double float 8
Array

Array为中共享内存的方法,为进程间安全的通信方式,不常用

from multiprocessing import Array

array = Array(typecode_or_type, size_or_initializer, lock=True)
'''
typecode_or_type: 类型选项
size_or_initializer: 
	- 如为一个整数,控制数组的长度,数组中值为0
	- 如为一个可迭代对象,长度为该对象长度,值为迭代中每个数据元素
lock: 默认为True,加锁维持同步
	- array.acquire() 加锁
	- array.release() 释放锁
'''
array.get_obj() # 获取数组中所有数据,如果为字符型,那么该函数会直接返回一个字符在一起的字符串
  • 代码示例
from multiprocessing import current_process,Process,Array
import time

def work_1(a):
    print('子进程work_1中:',a[:])
    a.acquire()
    time.sleep(5)
    a[0] = 1
    a.release()

def work_2(a):
    print('子进程work_2中:',a[:])
    a.acquire()
    a[0] = 2
    a.release()

def main():
    a = Array('i',1,lock=True) # 初始化int类型数组,长度为1
    p1 = Process(target=work_1,args=(a,))
    p2 = Process(target=work_2,args=(a,))
    work_list = [p1,p2]

    for work in work_list:
      	work.start() # 启动

    for work in work_list:
      	work.join() # 回收

    print('父进程中:',a[:])
    for var in a:
      	print(var)
if __name__ == '__main__':
	main()
Value

类似Array共享内存,但只支持单独的数据类型

from multiprocessing import Value
v = Value(typecode_or_type, *args, lock=True) 
v.acquire() # 加锁
v.release() # 放锁
v.value 
#获取其中数据
  • 代码示例
from multiprocessing import current_process,Process,Value

def work_1(v):
    print('子进程work_1拿到了中:',v.value)
    v.value = 1

def work_2(v):
    print('子进程work_2拿到了中:',v.value)
    v.value = 2

def main():
    v = Value('i',0,lock=False)
    p1 = Process(target=work_1,args=(v,))
    p2 = Process(target=work_2,args=(v,))
    work_list = [p1,p2]

    for work in work_list:
      	work.start()

    for work in work_list:
    	work.join()
		print('父进程中:',v.value)
if __name__ == '__main__':
	main()