python多线程的一点理解

理解这个其实需要懂一点操作系统的知识,不得不感叹学科之间其实很多都是有联系的。

其实多线程就比如泡面的时候一边烧开水一边放酱料,两不耽误。

在单核cpu中线程通过并发来实现cpu运算资源的高效使用

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)

 在多核cpu中由于每个内核都能跑一个线程,所以n个内核的cpu就能并行(注意这里是并行了不再是并发了)n个线程

但是当python在多核cpu中却存在一定的性能缺陷,这里我们试着多开几个线程看看

import threading, multiprocessing

def loop():
    x = 0
    while True:
        x = x ^ 1

if __name__=='__main__':
    for i in range(multiprocessing.cpu_count()):
        t = threading.Thread(target=loop)
        t.start()
        
        

这里开了和cpu个数相等的线程,按道理来说1个线程的死循环可以跑满1个内核,所有内核都跑一个循环cpu利用率肯定会爆炸吧

但是结果呢?

python多线程的一点理解_第1张图片

这里就 涉及到了GIL(Global Interpreter Lock)全局解释器锁在我查了各种资料后得出的结果就是,GIL是很久以前的

大佬为了防止线程崩溃设置的线程保护措施,简单来说  就是线程执行前先加一个全局锁,但这个锁只有1个,所以不管你

几个内核都只能同时跑1个线程这个锁不是python的特性,是解释器CPython的特性,像JPython就没有这个东西。

当时市面上还没有出现多核cpu,摩尔定律还没有失效,所以在当时这个东西还是很好用的,但随着技术进步这

个慢慢就成了python的累赘

 

来看解决办法,我了解到的方法是通过多进程来实现,试验了一下,确实有用

import threading, multiprocessing
from multiprocessing import Process
def loop():
    x = 0
    while True:
        x = x ^ 1

if __name__=='__main__':
    for i in range(multiprocessing.cpu_count()):
        t = Process(target=loop)
        t.start()
        

 

python多线程的一点理解_第2张图片

 

 至于为什么多进程可以实现,我在stackoverflow上看到的解答是,python为每个进程配一个解释器,这样下来

n个进程就有n个解释器,每个进程一个主线程,GIL就加在这个主线程上,自然就突破了GIL的性能限制。

(至于更深入的原理可能需要等更加深入学习才能解释出来)


这里需要明确的是,虽然有GIL但是并不代表python的多线程就是鸡肋,这个其实把我坑了有段时间,我一度以为python的多线程没有用,但实际上多线程在解决IO密集型的任务上依旧有很大的优势,毕竟人家就是为这个而生的。

你可能感兴趣的:(mysql)