• 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))
  • 相关阅读:
    多对多关系表的创建方式、forms组件
    SweetAler弹框插件与分页器插件
    Django数据库查询优化与AJAX
    django orm(2)
    Django orm(1)
    Django之视图层与模板层
    Django之路由层
    初识Django之前端后端与数据库的配置
    面试题49
    web框架之初识Django
  • 原文地址:https://www.cnblogs.com/fengxb1213/p/12814547.html
Copyright © 2020-2023  润新知