V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
jfry
V2EX  ›  Python

python3 中,为什么把 checkinterval 设置的非常小没有让 CPU 密集型多线程变慢?

  •  
  •   jfry ·
    toaco · 2018-05-20 15:53:38 +08:00 · 2500 次点击
    这是一个创建于 2386 天前的主题,其中的信息可能已经有所发展或是发生改变。
    from threading import Thread
    
    def countdown(start, end):
        while end > start:
            end -= 1
    
    def single_thread(n):
        countdown(0, n)
    
    def multi_thread(n):
        t1 = Thread(target=countdown, args=(0, n // 2))
        t2 = Thread(target=countdown, args=(n // 2, n))
        t1.start()
        t2.start()
        t1.join()
        t2.join()
    
    if __name__ == '__main__':
        import timeit
        import sys
    
        sys.setswitchinterval(1)
        print(timeit.timeit("""import gil;gil.multi_thread(10000000);""", number=1))
        # 1.07s
        sys.setswitchinterval(0.001)
        print(timeit.timeit("""import gil;gil.multi_thread(10000000);""", number=1))
        # 1.09s
    

    按照我的理解,将切换间隔设置的更小,导致更多次的线程睡眠 /唤醒操作,然后总的执行时间应该变长,但是这里并没有,谁能告诉我是为什么吗? 测试环境为:四核 Ubuntu python3.5

    4 条回复    2018-05-22 09:53:24 +08:00
    enenaaa
        1
    enenaaa  
       2018-05-20 17:26:25 +08:00
    第一, 线程切换时间依赖于操作系统。
    第二, 这个值只是解释器估计的理想时间。在执行较长的函数内并不会主动中断。因为解释器没有线程调度功能, 需要依赖系统。
    jfry
        3
    jfry  
    OP
       2018-05-21 20:29:11 +08:00
    @enenaaa @chenxytw 我是看了一个讲 Python3 GIL 的 PDF 之后做的这个实验,根据这个 PDF 中的描述,当两个线程 A,B 同时运行的时候,假如 A 正在运行,此时 B 会阻塞直到超时,然后设置 gil_drop_request 为 1,A 检测到之后就会释放 GIL 并且通过信号唤醒 B,因此我理解的是此时操作系统就会让 A 睡眠,然后调度 B .是我理解错了吗?
    PDF 地址: http://www.dabeaz.com/python/NewGIL.pdf
    enenaaa
        4
    enenaaa  
       2018-05-22 09:53:24 +08:00 via Android
    @jfry 线程切换的条件一是当前线程主动挂起,二是当前时间片用完。这两个条件都由系统决定,解释器是在系统切换完之后加锁。setswitchinterval 只是在解释器加锁时的一个参照时间,而不是系统的时间片时间。

    这个程序里线程一直在运行,用满系统时间片。导致解释器无从按指定参数去控制。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2749 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 14:58 · PVG 22:58 · LAX 06:58 · JFK 09:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.