进程与线程:
* 进程: 进程是系统中程序执行和资源分配的基本单元, 每个进程都有自己的数据段(存储数据), 代码段(存储代码), 堆栈段(对象和变量). # 全局变量等资源在多个进程中不能 共享, 在子进程中修改全局变量对父进程中的全局变量没有影响.
* 线程: 在一个进程内要同时干多件事, 就得同时运行多个 "子任务", 这些子任务称为线程; 每个线程共享这个进程的所有资源 (变量和数据等) 和内存空间, 所以在子线程里面可以修改该 进程的变量.
* 多任务: 操作系统可以同时运行多个任务, 每个任务就是一个进程或者一个线程.
* 并发: 并发是指一个处理器同时处理多个任务; 由于 cpu 调度执行的速度太快了, 所以看起来是同时执行, 实际上是轮流交替执行的.
* 并行: 并行是指多个处理器同时处理多个任务.
* 单核 cpu 实现多任务的原理: 操作系统轮流让各个任务交替执行, 由于 cpu 调度执行的速度太快了, 导致我们感觉就像所有的任务都在同时执行一样.
* 多核 cpu 实现多任务的原理: 由于实际任务数量是远远多于 cpu 的核心数量的, 所以操作系统会自动把很多任务轮流调度到每个核心上执行.
* 实现多任务的方式: 1. 多进程模式 (用的较多): 一个父进程, n 个子进程, 进程由操作系统来调度执行没有顺序; 要想让所有子进程结束后再让父进程结束, 可在子进程末尾使用 .join() 方 法.
2. 多线程模式 (用的最多): 一个父线程, n 个子线程, 线程由操作系统来调度执行没有顺序, 要想线程顺序执行, 需要加锁(Lock); 要想所有子线程结束后再让父线程 结束, 可在子线程末尾使用 .join() 方法.
3. 协程模式(用的很少): 协程看上去也是子程序, 但执行过程中, 在子程序的内部可中断, 然后转而执行别的子程序, 不是函数调用.
4. 多进程 + 多线程(一般不建议使用)
* 多进程模块: multiprocessing, 它里面的 Process 类是用来创建一个进程实例的, Pool 线程池类是用来创建多个进程实例的.
* 线程模块: threading, 它里面的 Thread 类是用来创建一个线程实例的, Lock 类是用来创建一个锁实例的.
* 计算机 IO 操作: IO 指的是计算机执行读写操作, 由于计算机执行读写操作的速度比 cpu 和内存的速度慢的多得多, 所以 C 语言这种底层计算机语言虽然 cpu 的速度比 python 快很多, 但是 有时候还是得等待计算机执行 IO 操作, 所以 python 在某些领域才有竞争力.
多进程:
- # 从多进程模块 (multiprocessing) 导入 Process 类
- from multiprocessing import Process
- import time
- import os
- # 定义子进程
- def run(str):
- while True:
- # os.getpid()获取进程 id, os.getppid()获取父进程 id
- print("process %s"%str,os.getpid(),os.getppid())
- # 延时 2 秒
- time.sleep(2)
- if __name__ == '__main__':
- print("父进程启动",os.getpid())
- # 创建子进程, 用 Process 类创建一个 pro 对象
- pro = Process(target=run,args=("1",))
- # 启动子进程
- pro.start()
- while True:
- print("process 2")
- time.sleep(2.5)
线程锁:
- # 线程锁的应用, 让线程顺序执行.
- import time # 导入时间模块
- import threading # 导入 threading 线程模块
- num = 10 # 设置一个全局变量
- lock = threading.Lock() # 创建一个锁实例
- def reduce_num(): # 定一个子线程函数 reduce_num
- print("子线程开始...")
- global num # 声明全局变量
- lock.acquire() # 获得一个锁对象
- temp = num # 读取全局变量 num
- num = temp - 1 # 把从全局拿来的变量进行减一的操作
- lock.release() # 释放掉锁
- print("子线程结束...\n")
- time.sleep(1) # 增加一个休眠功能
- if __name__ == '__main__':
- print("父线程启动")
- for i in range(10): # 从 0 到 10 进行循环
- t = threading.Thread(target=reduce_num) # 在循环中创建子线程, 共创建 10 个
- t.start() # 循环启动子线程
- t.join() # 让子线程结束后, 再让父线程结束
- print("Result:%s"%num) # 打印通经过多次子线程函数更改过的全局变量, 结果为 0 则实验成功.
- print("父线程结束")
结果: Result : 0
来源: http://www.bubuko.com/infodetail-2589123.html