python并发和线程

并发和并行的区别

  • 并行,parallel

    • 同时做某些事,可以互不干扰的同一个时刻做几件事
  • 并发,concurrency

    • 也是同时做某些事,但是强调一个时段内有事情要处理

举例:

  • 乡村公路一条车道,半幅路面出现了坑,交警指挥交通

  • 众多车辆在这一时段要通过路面的事件,这就是并发

  • 高速公路的车道,双向4车道,所有车辆(数据)可以互不干扰的在自己的车道上奔跑(传输)

  • 在同一时刻,每条车道上可能同时有车辆在跑,是同时发生的概念,这是并行。

并发的解决:
高并发的解决

  • -队列、缓冲区

    • 队列是一种天然解决并发的办法,解决了资源使用的问题
    • 拍成的队列其实就是一个缓冲地带,就是缓冲区
    • 可以有优先队列
    • 例如queue模块的类QueueLifoQueuePriorityQueue
  • 争抢

    • 只开一个窗口,可能没有秩序,也就是谁挤进去就给谁

    • 挤到窗口的人占据窗口,直到完成离开

    • 其他人继续争抢,会有一个占据窗口,可以视为锁定窗口,窗口就不能为其他人提供服务了,这是一种锁机制

    • 争抢也是一种高并发解决方案,但是,这样不好,因为可能有人很长时间抢不到

  • 预处理

    • 一种提前加载用户需要的数据的思路,预处理思想,缓存常用

    • 加载多少,区分热,冷数据

  • 并行

    • 一个队列搞不定,多开窗口形成多个队列,如同开多个车道一样,并行处理

    • 多开窗口,造成成本上升

    • 日常可以通过购买更多服务器,或多开进程、线程实现并行处理,来解决并发问题

    • 这些都是水平扩展思想

      • 如果线程在单CPU上处理,就不是并行了

      • 但是大多数服务器都是多CPU的,服务的部署往往是多机的、分布式的,这都是并行处理。

      • 2个CPU叫两路,每个CPU有多核,每一个核心认为是一个CPU

  • 提速

    • 提高单个窗口的处理速度,也是解决并发的方式

    • 提高单个CPU性能,或单个服务器安装更多的CPU

    • 这是一种垂直扩展思想

  • 消息中间件

    • 上地,西二旗地铁站外的九曲回廊的走廊,缓冲人流,进去之后在进行安检进站

    • 常见的消息中间件有RabbitMQActiveMQ(Apache)RocketMQ(阿里Apache)kafka(Apache)等。

    • 当然还有其他手段解决并发问题,但是已经列举除了最常用的解决方案,一般来说不同的并发场景用不同的策略,而策略肯能是多种。

    • 方式的优化组合

    • 技术来源于生活

进程和线程

  • 在实现了线程的操作系统中,线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。它被包含在进程之中,是进程中的实际单位。一个程序的执行实例就是一个进程。

  • 进程 (process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的而基本单位,是操作系统结构的基础。

进程和程序的关系

  • 程序是源代码编译后的文件,而这些文件存放在磁盘中。当程序被操作系统加载到内存中,就是进程,进程中存放着指令和数据(资源),它也是线程的容器
  • Linux进程有父进程、子进程,Windows的进程是平等关系。
  • 线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单位。
  • 一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。
  • 在许多系统中,创建一个线程比创建一个进程快10-100倍。

进程、线程的理解

  • 现代操作系统提出进程的概念,每一个进程都认为自己独占所有的计算机硬件资源。
  • 进程就是独立的王国,进程间不可以随便的共享数据
  • 线程就是省份,同一个进程内的线程可以共享进程的资源,每一个线程拥有自己独立的堆栈
    在这里插入图片描述
    在这里插入图片描述

python中的进程和线程

  • 进程会启动一个解释器进程,线程共享一个解释器进程
  • 一个线程跑一个函数

python的线程开发

  • 使用标准库threading
  • 通过threading.Thread创建一个线程对象,target是目标函数, name可以指定名称
  • 需要调用start方法,启动线程

线程退出

  • python没有提供线程退出的方法,线程在下面情况时退出:
    • 线程函数内语句执行完毕
    • 线程函数中抛出未处理的异常

python的线程没有优先级、没有线程组的概念,也不能被销毁、停止、挂起、那也就没有恢复、中断了。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • start()方法会调用run()方法,而run()方法运行函数
  • 使用start()启动线程,启动了一个新的线程,但是使用run(),并没有启动新的线程,就是在主线程中调用了一个普通的函数而已
  • 因此,启动线程需使用start()方法,才能启动多个线程

多线程

  • 一个进程中如果有多个线程,就是多线程,实现一种并发
  • 当使用start()启动线程后,进程内有多个活动的线程并行的工作,就是多线程。
  • 一个进程中至少有一个线程,并作为程序的入口,这个线程就是主线程。一个进程至少有一个主线程。

线程安全

  • 线程执行一段代码,不会产生不确定的结果,那这段代码就是线程安全的。
  • print()函数在线程中会被打断,被线程切换打断了,这种情况发生的时机不确定。print()函数分两步,第一步打印字符串,第二部换行,就在这之间,发生了线程的切换。
  • print()函数是线程不安全的
  • 如果是这样,多线程编程的时候,print输出日志,不能保证一个输出后面一定换行了,怎么办?
    • 不让print打印换行
      • format格式化输出,手动加换行 '\n'
      • 字符串是不可变的类型,它可以作为一个整体不可分割输出。end='' 就不在让print输出换行了。
    • 使用logging
      • 标准库里的logging模块,日志处理模块,线程安全的,生成环境代码都使用logging
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值