zoukankan      html  css  js  c++  java
  • python——多线程

    多线程特点:
      • 线程的并发是利用cpu上下文的切换(是并发,不是并行)
      • 多线程执行的顺序是无序的
      • 多线程共享全局变量
      • 线程是继承在进程里的,没有进程就没有线程
      • GIL全局解释器锁
      • 只要在进行耗时的IO操作的时候,能释放GIL,所以只要在IO密集型的代码里,用多线程就很合适
      • 占用资源小,效率慢

    # 无序的,并发的
    def test1(n):
        time.sleep(1)
        print('task', n)
    for i in range(10):
        t = threading.Thread(target=test1,args=('t-%s' % i,))
        t.start()
    
    
    
    #计算并发所用的时间
    import threading
    import time
    def test1(n):
        time.sleep(1)
        print('task', n)
    def test2(n):
        time.sleep(1)
        print('task', n)
    start = time.time()
    l = []
    t1 = threading.Thread(target=test1, args=(1,))
    t2 = threading.Thread(target=test1, args=(2,))
    t1.start()
    t2.start()
    l.append(t1)
    l.append(t2)
    for i in l:
        i.join()
    end = time.time()
    print(end - start)
    

      

    GIL的全称是:Global Interpreter Lock,意思就是全局解释器锁,这个GIL并不是python的特性,他是只在Cpython解释器里引入的一个概念,而在其他的语言编写的解释器里就没有这个GIL例如:Jython,Pypy
    为什么会有gil?:
           随着电脑多核cpu的出现核cpu频率的提升,为了充分利用多核处理器,进行多线程的编程方式更为普及,随之而来的困难是线程之间数据的一致性和状态同步,而python也利用了多核,所以也逃不开这个困难,为了解决这个数据不能同步的问题,设计了gil全局解释器锁。
    说到gil解释器锁,我们容易想到在多线程中共享全局变量的时候会有线程对全局变量进行的资源竞争,会对全局变量的修改产生不是我们想要的结果,而那个时候我们用到的是python中线程模块里面的互斥锁,哪样的话每次对全局变量进行操作的时候,只有一个线程能够拿到这个全局变量;看下面的代码:

    import threading
    global_num = 0
    def test1():
        global global_num
        for i in range(1000000):
            global_num += 1
    print("test1", global_num)
    def test2():
        global global_num
        for i in range(1000000):
            global_num += 1
    print("test2", global_num)
    t1 = threading.Thread(target=test1)
    t2 = threading.Thread(target=test2)
    t1.start()
    t2.start()
    在上面的例子里,我们创建了两个线程来争夺对global_num的加一操作,但是结果并非我们想要的,所以我们在这里加入了互斥锁
    
    import threading
    import time
    global_num = 0
    lock = threading.Lock()
    def test1():
        global global_num
        lock.acquire()
        for i in range(1000000):
            global_num += 1
        lock.release()
        print("test1", global_num)
    def test2():
        global global_num
        lock.acquire()
        for i in range(1000000):
            global_num += 1
        lock.release()
        print("test2", global_num)
    t1 = threading.Thread(target=test1)
    t2 = threading.Thread(target=test2)
    start_time = time.time()
    t1.start()
    t2.start()
    作者:无荨

    -------------------------------------------

    个性签名:学IT,就要做到‘活到老学到老’!

    如果觉得这篇文章对你有小小的帮助的话,别忘记点个“推荐”哦!

  • 相关阅读:
    eclipse下c/cpp " undefined reference to " or "launch failed binary not found"问题
    blockdev 设置文件预读大小
    宝宝语录
    CentOS修改主机名(hostname)
    subprocess报No such file or directory
    用ldap方式访问AD域的的错误解释
    英特尔的VTd技术是什么?
    This virtual machine requires the VMware keyboard support driver which is not installed
    Linux内核的文件预读详细详解
    UNP总结 Chapter 26~29 线程、IP选项、原始套接字、数据链路访问
  • 原文地址:https://www.cnblogs.com/twoo/p/11750356.html
Copyright © 2011-2022 走看看