• Python线程


    time.sleep与全局解释器锁

    Cpython解释器中有全局解释器锁(GIL),一次只允许使用一个线程执行Python字节码,因此一个python进程通常不能同时使用多个CPU核心。

    然而标准库中,所有C语言编写I/O操作的函数,等待操作系统返回结果时,都会释放GIL。

    比如像time.sleep()函数:作用是在一段时间不会返回或者执行其他代码。

    一段时间结束后,time.sleep也会释放GIL,从而允许其他线程进行。

    使用Python处理CPU密集型工作时,应该试试PyPy,futures模块。

    或者使用分布式计算引擎Apache Spark,支持把Python对象当做数据。

    多线程

    import time,datetime
    startTime=datetime.datetime(2029,10,31,0,0,0)
    while datetime.datetime.now() < startTime:
        time.sleep(1)
    
    print('Happy Halloween 2029')

    这段代码指定2029年10月31日作为开始时间,不断地调用time,sleep(1),在2029年10月31日没到那天,程序将一直“沉睡”。

    这是因为前面提到的全局解释器锁的原因。Python程序在默认的情况下,只有一个执行线程。

    单线程程序的执行就像一个”逐行”读书的手指,而多线程程序的执行可以为有多个“逐行”读书的手指。

    为了不必让所有代码等待,我们可以在原来的线程外,在创建一个线程,这个单独的线程可以执行延迟或安排的代码。

    为此我们可以这样做:

    import threading,time
    print('程序启动.')
    def takeANap():
        time.sleep(5)
        print('Wake up!')
    threadObj=threading.Thread(target=takeANap)
    threadObj.start()
    print('程序结束.')

     输出结果会是这样


    程序启动.

    程序结束.

    Wake up!


     为什么最后两个顺序是这样的呢?

    这是因为当程序运行到start()函数时,takeANap函数已经被放入一个新的执行线程中。这个时候相当于

    一个手指即将执行:print('程序结束.'),另一个手指已经在takeANap函数入口处,这个时候主线程会打印出程序结束内容,新线程会在小睡后打印Wake up!

    通常程序会在最后一行代码执行后终止,对于此例则有两个线程。在程序的所有执行线程终止前,程序不会终止。所以即使主线程已经完成使命,新线程仍会sleep。

    多线程会遇到的问题:并发问题

    如果这些线程同时读写变量,会导致互相干扰,最终会发生并发问题。

    有关线程的初学者教程更多见:

    http://nostarch.com/automatestuff/

  • 相关阅读:
    Blazor使用Chrome远程调试
    Blazor登录Ids4
    Jenkins + Coding 构建 Docker Image 并自动上传至Docker Registry
    EFK 数据生命周期
    EFK (Elasticsearch + Fluentd + Kibana) 日志分析系统
    通过Nginx代理Grafana,并通过域名访问
    Prometheus搜集mysql和nginx log指标
    java 线程相关(4)
    java 并发相关(5)
    java 线程相关(3)
  • 原文地址:https://www.cnblogs.com/liuguangshou123/p/13582748.html
Copyright © 2020-2023  润新知