python学习Day39--复习(前期+进程和线程相关)

一、前期复习

1、C/S架构与B/S架构:

  C/S架构:客服端 服务器模式

  B/S架构:浏览器 服务器模式

  B/S架构的客服端对PC机的性能要求较低。统一了应用的接口。B/S架构隶属于C/S架构。

2、TCP/UDP的区别:

  TCP:面向连接,可靠的,面向字节流

  UDP:不面向了解,不可靠,速度快,面向数据包的

3、TCP会发生粘包:

  粘包:数据混乱。发送端发送了数据后,接收端不知道应该如何去接收,导致数据混乱。

  合包机制:Nagle算法

  拆包机制

  注意:只有TCP协议才会发生粘包。

4、arp协议:

  通过目标的IP地址获取到目标的MAC地址。

5、OSI五层模型:

  应用层:        http, https, ftp

  传输层:        tcp, udp

  网络层:           ip协议

  数据链路层:      arp协议        网卡

  物理层:                   网线,电信号,集线器

6、交换机与路由器的区别:

  交换机主要用来组织局域网,进行同一网段之间的信息传输。

  路由器主要用来跨网段的信息传输,路由出最佳路径。

7、交换机的通信方式

  单播:点对点

  广播:吼一嗓子

  组播:点对多(一组或多台)

8、如何判断两台电脑是否处于同一网段?

  子网掩码 & ip地址

9、并行和并发?

  并行:同一时间点多个任务同时进行

  并发:在统一时间段内多个任务同时进行

10、进程和线程的区别?

  进程:是资源分配的基本单位

  线程:是最小的执行单位,线程不能独立拥有资源,必须依赖于所属进程。

  当计算密集时,多进程比较好。IO密集时,使用多线程。

11、锁

  GIL锁:全局解释锁。锁的是线程,宝成同一时间只允许一个线程访问CPU。

  互斥锁:一把锁配一把钥匙。主要用于保护数据安全

    共享资源,又叫做临界资源、共享代码,又叫做临界代码。

    对临界资源进行操作时,一定要加锁。

  递归锁:一把万能 钥匙配好多把锁。

12、信号量

  也是用来保护数据安全的。一把锁配多把钥匙。

13、事件:

  wait( ):判断is_set的bool值,如果为True,wait是非阻塞。

  set:将is_set的bool值设置为True。

  is_set:标识

  clear:将is_set的bool值设置为False

14、多线程:

  条件:Condition

  定时器:Timer(t, func)

15、多进程之间的通信:

  队列和管道

  队列是安全的,队列=管道+锁

  管道是不安全的。

16、队列实现生产者消费者模型

  这个模型主要是为了解耦

17、进程池的模块:Pool

  p.map

  p.apply( ):同步提交任务

  p.apply_async( ):异步提交任务

  回调函数:在进程池中,是父进程调用的回调函数。

二、进程池和线程池

1、同一个进程内的队列(多线程)

  优先级队列:queue.PriorityQueue( )

  q.put( )  接收的是一个元组

  元组中的第一个参数:表示当前数据的优先级

  元组中的第二个参数:需要存放到队列的数据

    优先级比较:(首先保证整个队列中,所有表示优先级的东西必须一致)

    ① int:比较数值大小

    ② str:比较字符串的大小,从第一个字符的ASCII码开始比较

2、线程池

  在一个池子里,放固定数量的线程,这些线程等待任务,一旦有任务来,就有线程自发的去执行任务。

 1 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
 2 from multiprocessing import Pool
 3 
 4 #  concurrent.futures 这个模块是异步调用的机制
 5 #  concurrent.futures 提交任务都是用submit
 6 #  for + submit 多个任务的提交
 7 #  shutdown 是等效于Pool中的close+join,是指不允许再继续向池中增加任务,然后让父进程(线程)等待池中所有进程执行完所有任务。
 8 
 9 # from multiprocessing import Pool.apply / apply_async
10 import time
11 
12 def func(num):
13     sum = 0
14     for i in range(num):
15         for j in range(i):
16             for x in range(j):
17                 sum += x ** 2
18     print(sum)
19 
20 if __name__ == '__main__':
21     pass
22     # pool的进程池的效率演示
23     # p = Pool(5)
24     # start = time.time()
25     # for i in range(100):
26     #     p.apply_async(func,args=(i,))
27     # p.close()
28     # p.join()
29     # print('Pool进程池的效率时间是%s'%(time.time() - start))
30 
31 
32     # 多进程的效率演示
33     # tp = ProcessPoolExecutor(5)
34     # start = time.time()
35     # for i in range(100):
36     #     tp.submit(func, i)
37     # tp.shutdown()  # 等效于 进程池中的 close + join
38     # print('进程池的消耗时间为%s' % (time.time() - start))
39 
40 
41 
42 
43     # 多线程的效率
44     # tp = ThreadPoolExecutor(20)
45     # start = time.time()
46     # for i in range(1000):
47     #     tp.submit(func,i)
48     # tp.shutdown()# 等效于 进程池中的 close + join
49     # print('线程池的消耗时间为%s'%(time.time() - start))
50 
51 
52 # 结果:针对计算密集的程序来说
53 #   不管是Pool的进程池还是ProcessPoolExecutor()的进程池,执行效率相当
54 #   ThreadPoolExecutor 的效率要差很多
55 #   所以 当计算密集时,使用多进程。
线程池与进程池的效率对比
 1 from concurrent.futures import ThreadPoolExecutor
 2 import time
 3 
 4 
 5 def func(num):
 6     sum = 0
 7     # time.sleep(5)
 8     # print(num) # 异步的效果
 9     for i in range(num):
10         sum += i ** 2
11     return sum
12 
13 t = ThreadPoolExecutor(20)
14 
15 
16 # 下列代码是用map的方式提交多个任务,对应 拿结果的方法是__next__()  返回的是一个生成器对象
17 res = t.map(func,range(1000))
18 t.shutdown()
19 print(res.__next__())
20 print(res.__next__())
21 print(res.__next__())
22 print(res.__next__())
23 
24 # 下列代码是用for + submit提交多个任务的方式,对应拿结果的方法是result
25 # res_l = []
26 # for i in range(1000):
27 #     re = t.submit(func,i)
28 #     res_l.append(re)
29 # # t.shutdown()
30 # [print(i.result()) for i in res_l]
31 
32 # 在Pool进程池中拿结果,是用get方法。   在ThreadPoolExecutor里边拿结果是用result方法
线程池的返回值

3、回调函数

  无论是ProcessPoolExecutor的进程池,还是Pool的进程池,回调函数都是父进程调用的。

 1 from concurrent.futures import ProcessPoolExecutor
 2 # 不管是ProcessPoolExecutor的进程池  还是Pool的进程池,回调函数都是父进程调用的。
 3 import os
 4 import requests
 5 
 6 
 7 def func(num):
 8     sum = 0
 9     for i in range(num):
10         sum += i ** 2
11     return sum
12 
13 def call_back_fun(res):
14     # print(res.result(),os.getpid())
15     print(os.getpid())
16 
17 if __name__ == '__main__':
18     print(os.getpid())
19     t = ProcessPoolExecutor(20)
20     for i in range(1000):
21         t.submit(func,i).add_done_callback(call_back_fun)
22     t.shutdown()
回调函数

4、条件

  条件涉及的4个方法:

1 con.acquire()
2 con.release()
3 con.wait()  # 假设有一个初始状态为False,阻塞。一旦接受到notify的信号后,变为True,不再阻塞
4 con.notify(int)  给wait发信号,发int个信号,会传递给int个wait,让int个线程正常执行
 1 from threading import Condition,Thread
 2 import time
 3 
 4 
 5 def func(con,i):
 6     con.acquire()# 主线程和10个子线程都在抢夺递归锁的一把钥匙。
 7     # 如果主线程抢到钥匙,主线程执行while 1,input,然后notify发信号,还钥匙。但是,此时如果主线程执行特别快
 8     # 极有可能接下来主线程又会拿到钥匙,那么此时哪怕其他10个子线程的wait接收到信号,但是因为没有拿到钥匙,所以其他子线程还是不会执行
 9     con.wait()
10     print('第%s个线程执行了'%i)
11     con.release()
12 
13 con = Condition()
14 for i in range(10):
15     t = Thread(target=func,args = (con,i))
16     t.start()
17 while 1:
18     # print(123)
19     con.acquire()
20     num = input('>>>')
21     con.notify(int(num))
22     con.release()
23     time.sleep(0.5)
24 
25 # 条件 涉及 4个方法:
26 #     con.acquire()
27 #     con.release()
28 #     con.wait()  # 假设有一个初始状态为False,阻塞。一旦接受到notify的信号后,变为True,不再阻塞
29 #     con.notify(int)  给wait发信号,发int个信号,会传递给int个wait,让int个线程正常执行
条件

5、queue模块

 1 from multiprocessing import Queue# 是用于多进程的队列,就是专门用来做进程间通信(IPC)。
 2 import queue# 是用于同一进程内的队列,不能做多进程之间的通信
 3 
 4 # q = queue.Queue()
 5 # # 先进先出
 6 # q.put(1)
 7 # q.put(2)
 8 # q.put(3)
 9 # print(q.get())
10 # print(q.get())
11 
12 # q = queue.LifoQueue()
13 # # 后进先出的队列
14 # q.put(1)
15 # q.put(2)
16 # q.put(3)
17 # print(q.get())
18 
19 q = queue.PriorityQueue()
20 # 优先级队列,put()方法接收的是一个元组(),第一个位置是优先级,第二个位置是数据
21 # 优先级如果是数字,直接比较数值
22 # 如果是字符串,是按照 ASCII 码比较的。当ASCII码相同时,会按照先进先出的原则
23 q.put((1,'abc'))
24 q.put((5,'qwe'))
25 q.put((-5,'zxc'))
26 print(q.get())
27 print(q.get())
28 print(chr(48))
原文地址:https://www.cnblogs.com/fengxb1213/p/12814547.html