【廖雪峰老师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教程】——进程与线程

原文地址:https://www.cnblogs.com/ChaoyuanJam/p/9749718.html

时间: 2024-10-17 17:43:02

【廖雪峰老师python教程】——进程与线程的相关文章

【廖雪峰老师python教程】——OOP

概述 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 数据封装.继承和多态是面向对象的三大特点,我们后面会详细讲解. 由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去.通过定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑上去: 类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有

【廖雪峰老师python教程】——IO编程

同步IO 异步IO 最常见的IO--读写文件 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件). open() read() close() try: f = open('/path/to/file', 'r') print(f.read()) finally

进程 vs. 线程(python的协程)(转廖雪峰老师python教程)

我们介绍了多进程和多线程,这是实现多任务最常用的两种方式.现在,我们来讨论一下这两种方式的优缺点. 首先,要实现多任务,通常我们会设计Master-Worker模式,Master负责分配任务,Worker负责执行任务,因此,多任务环境下,通常是一个Master,多个Worker. 如果用多进程实现Master-Worker,主进程就是Master,其他进程就是Worker. 如果用多线程实现Master-Worker,主线程就是Master,其他线程就是Worker. 多进程模式最大的优点就是稳

廖雪峰老师Python教程读后笔记

廖老师网站:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 花几天时间看了廖老师的python教程,现在总结一下. (本人用python工作了一年半,有一定python基础,看过<python核心编程>与部分<python源码剖析>,只把自己觉得有用的记一下) 高级特性 切片,对list和tuple而言 生成器yield,协程用到,用于异步 迭代器Iterable(

git常用命令总结--廖雪峰老师Git教程命令总结

学习了廖雪峰老师的Git教程之后的命令总结,重点关于git和远程仓库的东西. 如果没有学过,这是传送门 下面这个图很重要 一.git初始化本地仓库和配置 echo "想输入到文件的内容,一般为# 库名字" >> README.md git init  初始化一个仓库 如果没有配置需要配置 git config --list git config --global user.email "[email protected]" git config --gl

廖雪峰的Python教程之第一个Python程序

一.命令行模式和Python交互模式的区分 命令行模式: Python交互模式 二.文本编辑器 1.绝对不能用Word和Windows自带的记事本.Word保存的不是纯文本文件,而记事本会自作聪明地在文件开始的地方加上几个特殊字符(UTF-8 BOM),结果会导致程序运行出现莫名其妙的错误.文本编辑器可用Notepad++.Sublime Text.EditPlus,个人用EditPlus比较多 2.注意print前面不要有任何空格. 3.用文本编辑器写Python程序,然后保存为后缀为.py的

asyncio创建协程解析——分析廖雪峰的Python教程之创建WEB服务(转)

第一步,搭建开发环境 所需第三方库: aiohttp,异步 Web 开发框架:jinja2,前端模板引擎:aiomysql,异步 mysql 数据库驱动 所需内置库: logging,系统日志:asyncio,异步IO:os,系统接口:json,json 编码解码模块:time,系统时间模块:datetime,日期模块 接下来仅对用到的功能进行讲解 第二步,构建 Web 框架 主要思路: 理解 asyncio.aiohttp 基本应用 使用 asyncio 异步 IO 模块创建服务协程,监听相应

git常用命令,参照廖雪峰老师的git教程

git的常用命令 写在开篇: 作为一个菜鸟,我想学习的最好的方式就是边学边记笔记,这里只是本人写的自己通过学习了廖雪峰老师的git教程之后自己做的笔记,个人理解,可能有失偏颇,如想学习更专业更权威的git知识,请移步廖雪峰老师的官网 一.创建git仓库 1.git init  在本地创建一个空的仓库 2.在远程创建一个项目仓库,gitHub内操作 git remote add origin ***** 通过这两个步骤,就将本地仓库与远程仓库关联起来,然后在本地coding,提交代码到远程.也可以

廖雪峰的Python3教程: 章节1,章节2,章节3

目录 廖雪峰的Python3教程: 章节1,章节2,章节3 1 python简介 2 安装Python 2-1 Python解释器 3 第一个Python程序 3-1 使用文本编辑器 3-2 Python代码运行助手 3-3 输入和输出 廖雪峰的Python3教程: 章节1,章节2,章节3 教程地址 1 python简介 Python是著名的"龟叔"Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言,解释型语言,高级语言. Python提供