03-12 56—60

______egon新书python全套来袭请看:https://egonlin.com/book.html

56.读数据进程执行的代码:def read(q):

while True:
if not q.empty():
	value = q.get(True)
	print('Get %s from queue.' % value)
	time.sleep(random.random())
else:
	break
if __name__=='__main__':
# 父进程创建Queue,并传给各个子进程:
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    # 启动子进程pw,写入:
    pw.start()

    # 等待pw结束:
    pw.join()

    # 启动子进程pr,读取:
    pr.start()
    pr.join()
    # pr进程里是死循环,无法等待其结束,只能强行终止:
    print('')
    print('所有数据都写入并且读完') 进程池Pool
from multiprocessing import Poolimport os, time, random
def worker(msg):
	t_start = time.time()
	print("%s开始执行,进程号为%d" % (msg,os.getpid()))
	# random.random()随机生成0~1之间的浮点数 7.    time.sleep(random.random()*2)
	t_stop = time.time()
	print(msg,"执行完毕,耗时%0.2f" % (t_stop-t_start))
	po = Pool(3)  # 定义一个进程池,最大进程数3
	for i in range(0,10): 13.    # Pool().apply_async(要调用的目标,(传递给目标的参数元祖,))
	# 每次循环将会用空闲出来的子进程去调用目标    po.apply_async(worker,(i,))
	print("----start----")
	po.close()  # 关闭进程池,关闭后po不再接收新的请求 po.join()  # 等待po中所有子进程执行完成,必须放在close 语句之后 print("-----end-----")

57.multiprocessing.Pool 常用函数解析:

apply_async(func[, args[, kwds]]):使用非阻塞方式调用func(并行执行,堵塞方式必须等待上一个进程退出才能执行下一个进程),args为传递给func的参数列表,kwds为传递给func的关键字参数列表;
close():关闭Pool,使其不再接受新的任务;
terminate():不管任务是否完成,立即终止;
join():主进程阻塞,等待子进程的退出, 必须在close或terminate之后使用;
进程池中使用Queue
如果要使用Pool创建进程,就需要使用multiprocessing.Manager()中的 Queue(),而不是
multiprocessing.Queue(),否则会得到一条如下的错误信息:

RuntimeError: Queue objects should only be shared between processes through
inheritance.
from multiprocessing import Manager,Poolimport os,time,random
def reader(q):
    print("reader启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))
    for i in range(q.qsize()):
    print("reader从Queue获取到消息:%s" % q.get(True))
def writer(q):
    print("writer启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))
    for i in "itcast":
    q.put(i)
if __name__=="__main__":
    print("(%s) start" % os.getpid())
    q = Manager().Queue()  # 使用Manager中的Queue
    po = Pool()
    po.apply_async(writer, (q,))
    time.sleep(1)

    # 先让上面的任务向Queue存入数据,然后再让下面的任务开始从中取数据 po.apply_async(reader, (q,))
    po.close()
    po.join()
    print("(%s) End" % os.getpid())

58.谈谈你对多进程,多线程,以及协程的理解,项目是否用?

这个问题被问的概率相当之大,其实多线程,多进程,在实际开发中用到的很少,除非是那些对项目性能要求特别高的,有的开发工作几年了,也确实没用过,你可以这么回答,给他扯扯什么是进程,线程(cpython中是伪多线程)的概念就行,实在不行你就说你之前写过下载文件时,用过多线程技术,或者业余时间用过多线程写爬虫,提升效率。

'''
进程:一个运行的程序(代码)就是一个进程,没有运行的代码叫程序,进程是系统资源分配的最
小单位,进程拥有自己独立的内存空间,所以进程间数据不共享,开销大。

线程:  调度执行的最小单位,也叫执行路径,不能独立存在,依赖进程存在一个进程至少有一个线程,叫主线程,而多个线程共享内存(数据共享,共享全局变量),从而极大地提高了程序的运行效率。

协程:是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。

协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存
器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切
换非常快。
'''

59.解释一下什么是锁,有哪几种锁?

锁(Lock)是 Python 提供的对线程控制的对象。有互斥锁、递归锁。

60.什么是死锁呢?

若干子线程在系统资源竞争时,都在等待对方对某部分资源解除占用状态,结果是谁也不愿先解锁,互相干等着,程序无法执行下去,这就是死锁。
GIL锁(有时候,面试官不问,你自己要主动说,增加b格,尽量别一问一答的尬聊,不然最后等到的一句话就是:你还有什么想问的么?)
GIL锁 全局解释器锁(只在cpython里才有)
作用:限制多线程同时执行,保证同一时间只有一个线程执行,所以cpython里的多线程其实是伪多线程!
所以Python里常常使用协程技术来代替多线程,协程是一种更轻量级的线程,
进程和线程的切换时由系统决定,而协程由我们程序员自己决定,而模块gevent下切换是遇到了耗时操作才会切换。
三者的关系:进程里有线程,线程里有协程。
posted @ 2019-10-22 21:25  小猿取经-林海峰老师  阅读(670)  评论(0编辑  收藏  举报