进程
1、进程间内存是否共享?如何实现通讯?
不能共享 ,通过ipc 机制,管道队列实现
2、请聊聊进程队列的特点和实现原理?
先进先出.后进后出的特点. 实现原理是管道加pickel
3、请画出进程的三状态转换图
就绪 运行
阻塞
4、你了解生产者模型消费者模型么?如何实现?
from mu......ing import Proess
from mu...ing import Queue
def Prouter(q,food_name):
for i in rang(10):
food ='%s,%s'%(food_name,i)
print('生产了%s'%food')
q.put(food)
def Couster(q,name):
while 1:
food =q.get()
if not food:break
print('%s吃了%s'%(name,food))
q =Queque(5)
p1 =Process(targer=Product ,args =(q,'baozi'))
p2 =Process(targer=Product ,args =(q,'jiaozi'))
c1 =Process(targer=Couster,args=((q,''libai')))
c2 =Process(targer=Couster,args=((q,''dufu')))
p1.start()
p2.start()
c1.start()
c2.start()
p1.join()
p2.join()
q.put(None)
q.put(None)
5、从你的角度说说进程在计算机中扮演什么角色?
进程是计算机中最小的资源分配单位
线程
1、GIL锁是怎么回事?
GIL锁是线程中的全局解释器,保证同一时刻只能允许一个线程运行,以此来控制同一时间内共享数据只能被一个任务所修改,进而保证数据安全。
2、在python中是否线程安全?
安全
3、什么叫死锁?
多个进程在运行过程中----抢夺资源而造成的一种僵局
如果没有外力推进-----处于僵局中的进程无法继续进行
导致死锁的4个必要条件:
互斥。一次------只有一个进程----可以使用一个资源
不可抢占。不能抢占---进程已经占有的资源
循环等待。存在封闭的进程链---每个进程----此链中---下一个进程需要的资源
占有且等待。一个进程等待其他进程---继续占有----已经分配到的资源
4、logging模块是否是线程安全的?
安全
5、threading.local的作用?
线程中保证数据独立
6、程序从flag a执行到falg b的时间大致是多少秒?
import threading
import time
def _wait():
time.sleep(60)
# flag a
t = threading.Thread(target=_wait,daemon = False)
t.start()
# flag b
小于1m
7、程序从flag a执行到falg b的时间大致是多少秒?
import threading
import time
def _wait():
time.sleep(60)
# flag a
t = threading.Thread(target=_wait,daemon = True)
t.start()
# flag b
小于1秒
8、程序从flag a执行到falg b的时间大致是多少秒?
import threading
import time
def _wait():
time.sleep(60)
# flag a
t = threading.Thread(target=_wait,daemon = True)
t.start()
t.join()
# flag b
大于60miao
9、读程序,请确认执行到最后number是否一定为0
import threading
loop = int(1E7)
def _add(loop:int = 1):
global number
for _ in range(loop):
number += 1
def _sub(loop:int = 1):
global number
for _ in range(loop):
number -= 1
number = 0
ta = threading.Thread(target=_add,args=(loop,))
ts = threading.Thread(target=_sub,args=(loop,))
ta.start()
ts.start()
ta.join()
ts.join()
10、读程序,请确认执行到最后number是否一定为0
import threading
loop = int(1E7)
def _add(loop:int = 1):
global number
for _ in range(loop):
number += 1
def _sub(loop:int = 1):
global number
for _ in range(loop):
number -= 1
number = 0
ta = threading.Thread(target=_add,args=(loop,))
ts = threading.Thread(target=_sub,args=(loop,))
ta.start()
ta.join()
ts.start()
ts.join()
11、读程序,请确认执行到最后number的长度是否一定为1
import threading
loop = int(1E7)
def _add(loop:int = 1):
global numbers
for _ in range(loop):
numbers.append(0)
def _sub(loop:int = 1):
global number
while not numbers:
time.sleep(1E-8)
numbers.pop()
number = [0]
ta = threading.Thread(target=_add,args=(loop,))
ts = threading.Thread(target=_sub,args=(loop,))
ta.start()
ta.join()
ts.start()
ts.join()
12、读程序,请确认执行到最后number的长度是否一定为1
import threading
loop = int(1E7)
def _add(loop:int = 1):
global numbers
for _ in range(loop):
numbers.append(0)
def _sub(loop:int = 1):
global number
while not numbers:
time.sleep(1E-8)
numbers.pop()
number = [0]
ta = threading.Thread(target=_add,args=(loop,))
ts = threading.Thread(target=_sub,args=(loop,))
ta.start()
ts.start()
ta.join()
ts.join()
协程
1、什么是协程?常用的协程模块有哪些?
协程是一种用户态的轻量级线程,协程的调度完全由用户控制。
greenlet
gevent
2、协程中的join是用来做什么用的?它是如何发挥作用的?
等待开启的协成结束
3、使用协程实现并发的tcp server端
import socket from gevent import monkey monkey.patch_all() import gevent def talk(conn): while True: msg = conn.recv(1024).decode() conn.send(msg.upper().encode('utf-8')) sk =socket.socket() sk.bind(('127.0.0.1',8500)) sk.listen() while True: conn,addr = sk.accept() gevent.spawn(talk,conn)
4、在一个列表中有多个url,请使用协程访问所有url,将对应的网页内容写入文件保存
from gevent import monkey monkey.patch_all() import gevent from urllib import request import time def func(name,url): ret = request.urlopen(url) with open(name+'2.html','wb')as f: f.write(ret.read()) url_lst = [ ('python','https://www.python.org/'), ('blog','http://www.cnblogs.com/Eva-J/articles/8324673.html'), ('pypi','https://pypi.org/project/pip/'), ('blog2','https://www.cnblogs.com/z-x-y/p/9237706.html'), ('douban','https://www.douban.com/') ] start = time.time() g_list =[] for url_item in url_lst: g = gevent.spawn(func,*url_item) g_list.append(g) gevent.joinall(g_list) end = time.time() print('协程打开方式',end-start)
综合
1、进程和线程的区别
1、每启动一个进程,进程内都至少有一个线程。
2、进程本身只是一个资源单位,并不能真正执行,进程内开的线程才是真正的运行单位。
3、一个进程内可以启动多个线程,同一进程内线程间共享资源。
4、启线程的开销远远小于开进程。
5、线程可以相当程度控制相同进程下的线程,进程只能控制其子进程。
6、对主线程的更改(取消、优先级更改等)可能会进程的其他线程的行为;对父进程的修改则不会影响子进程。
2、进程池、线程池的优势和特点
进程池:节省进程资源,速度比进程快
线程池:速度比线程快.提高线程的可管理性,提高响应速度
3、线程和协程的异同?
协程是一种用户态的轻量级线程,协程的调度完全由用户控制。
协程与线程区别:
1、必须在只有一个单线程里实现并发
2、线程进程都是同步机制,而协程则是异步
3、修改共享数据不需加锁(本质是一个一个执行,因此不需要考虑加锁)
4、协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态(自己控制切换)
4、请简述一下互斥锁和递归锁的异同?
互斥锁lock为资源引入一个状态:锁定/非锁定。某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。
RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源
5、请列举一个python中数据安全的数据类型?
6、Python中如何使用线程池和进程池
import os
import time
from multiprocessing import Pool
def fun1(i):
time.sleep(1)
print(i,os.getpid())
if __name__ == '__main__':
p =Pool(4)
for i in range(10):
p.apply_async(fun1,args=(i,))
p.close()
p.join()
from threading import current_thread
from concurrent.futures import ThreadPoolExecutor
import time
def fun1(i):
time.sleep(1)
print('子线程%s'%i,current_thread().ident)
return i**2
tp =ThreadPoolExecutor(4)
rel_1 =[]
for i in range(20):
ret =tp.submit(fun1,i)
rel_1.append(ret)
for i in rel_1:
print(i.result())
7、简述 进程、线程、协程的区别 以及应用场景?
8、什么是IO多路复用及其作用
9、select、poll、epoll 模型的区别?
10、什么是并行,什么是并发?
-
并发是指一个处理器同时处理多个任务,看起来多个进程像在同时运行
-
并行是指多个处理器或者是多核的处理器同时处理多个不同的任务。
11、请解释同步和异步这两个概念?
12、请谈谈对异步非阻塞的了解?
13、简述信号量的实现原理
14、程序中的阻塞有哪些?给程序带来了哪些影响?
15、请分别用多进程、多线程、协程实现生产者消费者模型?