【廖雪峰老师python教程】——进程与线程
多进程
- 操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去。表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。
- 对于操作系统来说,一个任务就是一个进程(Process)
- 在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。
multiprocessing模块就是跨平台版本的多进程模块from multiprocessing import Process
import os # 子进程要执行的代码
def run_proc(name):
print('Run child process %s (%s)...' % (name, os.getpid())) if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Process(target=run_proc, args=('test',))
print('Child process will start.')
p.start()
p.join()#等待子进程结束,才继续往下进行
print('Child process end.')Parent process 928.
Process will start.
Run child process test (929)...
Process end.- 进程池
from multiprocessing import Pool
import os, time, random def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start))) if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Pool(4)
for i in range(5):
p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()# 必须先关闭,才能停止添加进程,才能运行
p.join()
print('All subprocesses done.')Parent process 669.
Waiting for all subprocesses done...
Run task 0 (671)...
Run task 1 (672)...
Run task 2 (673)...
Run task 3 (674)...
Task 2 runs 0.14 seconds.
Run task 4 (673)...
Task 1 runs 0.27 seconds.
Task 3 runs 0.86 seconds.
Task 0 runs 1.41 seconds.
Task 4 runs 1.91 seconds.
All subprocesses done.
多线程
import time, threading # 新线程执行的代码:
def loop():
print('thread %s is running...' % threading.current_thread().name)
n = 0
while n < 5:
n = n + 1
print('thread %s >>> %s' % (threading.current_thread().name, n))
time.sleep(1)
print('thread %s ended.' % threading.current_thread().name) print('thread %s is running...' % threading.current_thread().name)
t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()
print('thread %s ended.' % threading.current_thread().name)- 多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。【锁机制】
balance = 0
lock = threading.Lock() def run_thread(n):
for i in range(100000):
# 先要获取锁:
lock.acquire()
try:
# 放心地改吧:
change_it(n)
finally:
# 改完了一定要释放锁:
lock.release() 多线程编程,模型复杂,容易发生冲突,必须用锁加以隔离,同时,又要小心死锁的发生。
Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核。多线程的并发在Python中就是一个美丽的梦
ThreadLocal
在多线程环境下,每个线程都有自己的数据。一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁。
但是局部变量也有问题,就是在函数调用的时候,传递起来很麻烦:
一个ThreadLocal变量虽然是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。ThreadLocal解决了参数在一个线程中各个函数之间互相传递的问题。
import threading # 创建全局ThreadLocal对象:
local_school = threading.local() def process_student():
# 获取当前线程关联的student:
std = local_school.student
print('Hello, %s (in %s)' % (std, threading.current_thread().name)) def process_thread(name):
# 绑定ThreadLocal的student:
local_school.student = name
process_student() t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()
Hello, Alice (in Thread-A)
Hello, Bob (in Thread-B)
- 对应到Python语言,单线程的异步编程模型称为协程,有了协程的支持,就可以基于事件驱动编写高效的多任务程序。
分布式进程
- 在Thread和Process中,应当优选Process,因为Process更稳定,而且,Process可以分布到多台机器上,而Thread最多只能分布到同一台机器的多个CPU上
- 后期可以学习,现在用不上
【廖雪峰老师python教程】——进程与线程的更多相关文章
- 进程 vs. 线程(python的协程)(转廖雪峰老师python教程)
我们介绍了多进程和多线程,这是实现多任务最常用的两种方式.现在,我们来讨论一下这两种方式的优缺点. 首先,要实现多任务,通常我们会设计Master-Worker模式,Master负责分配任务,Work ...
- 廖雪峰老师Python教程读后笔记
廖老师网站:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 花几天时间看了廖老师的 ...
- python 协程(单线程中的异步调用)(转廖雪峰老师python教程)
协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在 ...
- 【廖雪峰老师python教程】——IO编程
同步IO 异步IO 最常见的IO——读写文件 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一 ...
- 【廖雪峰老师python教程】——错误和调试
错误处理 try...except...finally...机制 try: print('try...') r = 10 / 0 print('result:', r) except ZeroDivi ...
- 【廖雪峰老师python教程】——OOP
概述 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 数据封装.继承和多态 ...
- 【廖雪峰老师python教程】——模块
使用模块 任何模块代码的第一个字符串都被视为模块的文档注释: 使用__author__变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名: 当我们在命令行运行模块文件时,Python解释器把 ...
- 【廖雪峰老师python教程】——装饰器
装饰器 # 一个函数装饰器的列子 def log(func): def wrapper(*args,**kwargs): print('Name=%s'%func.__name__) return f ...
- 【廖雪峰老师python教程】——filter/sorted
filter Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数依次作用于每个元素,然 ...
随机推荐
- 剑指offer13 在O(1)时间删除链表的结点
把下一个节点的值直接赋值给要删除的节点,然后删除下一个节点.当这样做会有两个bad case:被删除的链表结点的下一个结点为空指针,如果链表只有一个结点.其实链表只有一个结点应该属于下一个结点为空指针 ...
- Leetcode 225 两个队列实现栈
Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...
- spring使用 hibernate jpa JpaRepository
使用JpaRepository需要两个架包: <dependency> <groupId>org.springframework.data</groupId> &l ...
- HDU 1019 (多个数的最小公倍数)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1019 Least Common Multiple Time Limit: 2000/1000 MS (J ...
- UCOS阅读问题累积
1.#ifdef __cplusplus extern "C" { #endif 作用: 一般用于将C++代码以标准C形式输出(即以C的形式被调用),这是因为C++虽然常被认 ...
- java中强引用、软引用、弱引用、幻象引用有什么区别?分别使用在什么场景?
不同的引用类型,主要体现在对象的不同可达性(reachable)状态和对垃圾收集的影响. 1.强引用是我们最常见的普通对象引用,只要还有强引用指向一个对象,就表明对象还"活着",垃 ...
- Swift _ OC _ 混编
Swift _ OC _ 混编 在OC环境下使用Swift. GitHub源码
- vsCode中误删了文件,教你怎么恢复
不要慌!下面开始帮你找到,很简单!
- CF1066CBooks Queries(数组的特殊处理)
题意描述 您需要维护一个数据结构,支持以下三种操作: L id:在现在序列的左边插一个编号为id的物品 R id:在现在序列的右边插一个编号为id的物品 ? id:查询该点左面有几个元素,右面有几个元 ...
- ATM购物作业
一. 基本需求 模拟实现一个ATM + 购物商城程序 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 支持多账户登录 支持账户间转账 记录日常消费 ...