个人博客

网络编程的基本概念

并发编程之——多进程

并发编程之——多线程

进程关于数据共享

生产者消费者模型

开启进程的 两种方式

put_nowait与get_nowait

锁的概念以及 模拟抢票练习

进程之间的内存空间是隔离的

进程间通信——生产者消费者模型

利用生成器制作一个简单的进度条

模拟远程SSH执行命令的编解码说明

Python Cookbook中关于并发的例子

基于线程池的多并发Socket程序的实现

在socket的server端处理client端发来的数据

5个线程:t1、t2先关闭,t3在t4与t5之后关闭

利用队列Queue实现一个多并发“线程池”效果的Socket程序

线程1:基本概念、线程的基础操作(阻塞与延迟的理解)、多线程与多进程的效率差、数据共享问题、线程的其他方法

线程2:enumerate方法、守护线程、线程锁、死锁现象(递归锁与互斥锁)、线程队列、进程池与线程池

重要概念

GIL——全局解释器锁

GIL的全称是Global Interpreter Lock,

  • python中一个线程对应于c语言中的一个线程
  • GIL使得同一个时刻只有一个线程在一个cpu上执行字节码, 无法将多个线程映射到多个cpu上执行
  • GIL会根据执行的字节码行数以及时间片释放gil, gil在遇到io的操作时候主动释放

GIL的特点

  • Python在多线程下,每个线程的执行方式为:

  • 获取GIL

  • 执行代码直到sleep或者是python虚拟机将其挂起。
  • 释放GIL

一个CPU只能执行一个线程, 例如一个CPU 有三个线程, 首先线程A执行, 然后线程A达到释放条件进行释放GIL, 线程B和线程C进行竞争GIL, 谁抢到GIL, 继续执行.

GIL无法保证线程绝对安全

total = 0

def add():
    global total
    for i in range(1000000):
        total += 1

def desc():
    global total
    for i in range(1000000):
        total -= 1

import threading
thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
thread2.start()

thread1.join()
thread2.join()
print(total)
"""
每一次的结果都不一样!
"""

守护进程

本身是一个子进程。

守护的是“主进程的代码”(就是 if __name__ == '__main__'下面的代码) —— 正常情况不设置守护进程!

结束条件:主进程的代码结束(主进程的代码结束不代表主进程结束--主进程比主进程代码要长!)!守护进程才结束!

因为守护进程也是一个子进程,他必须在主进程结束之前结束!因此它结束的节点是“主进程代码结束”

具体过程:主进程的代码结束,守护进程结束;主进程要回收子进程的资源;主进程等待其他所有的子进程结束;主进程回收所有子进程的资源!

为什么主进程要等待子进程结束之后才结束

​ ——因为主进程要负责给子进程回收一些系统的资源