精华内容
下载资源
问答
  • - 多线程的理解: 多进程和多线程都可以执行多个任务,线程是进程的一部分。...Python多线程并不能真正能发挥作用,因为在Python中,有一个GIL,即全局解释锁,该锁的存在保证在同一个时间只能有...

    -

    多线程的理解:

    多进程和多线程都可以执行多个任务,线程是进程的一部分。线程的特点是线程之间可以共享内存和变量,资源消耗少(不过在Unix环境中,多进程和多线程资源调度消耗差距不明显,Unix调度较快),缺点是线程之间的同步和加锁比较麻烦。

    Python多线程的缺陷:
    Python多线程并不能真正能发挥作用,因为在Python中,有一个GIL,即全局解释锁,该锁的存在保证在同一个时间只能有一个线程执行任务,也就是多线程并不是真正的并发,只是交替得执行。假如有10个线程炮在10核CPU上,当前工作的也只能是一个CPU上的线程。

    导致了程序应用了多线程下性能反而下将的问题。

    Python多线程的应用场景:
    虽然Python多线程有缺陷,总被人说成是鸡肋,但也不是一无用处,它很适合用在IO密集型任务中。I/O密集型执行期间大部分是时间都用在I/O上,如数据库I/O,较少时间用在CPU计算上。因此该应用场景可以使用Python多线程,当一个任务阻塞在IO操作上时,我们可以立即切换执行其他线程上执行其他IO操作请求。

    总结:Python多线程在IO密集型任务中还是很有用处的,而对于计算密集型任务,应该使用Python多进程。

    -

    拓展:

    python3异步多线程:https://blog.csdn.net/weixin_41827162/article/details/84104421

    以我的理解,上文提到的GIL只是同步多线程,异步多线程(上面链接博文)应该能解决任务阻塞的问题。

    造成这个GIL的原因是,线程start()了以后又执行了join(),所以,不要使用join()(join()控制了线程的同步与异步,提高了线程的安全性)即可。

    -

    展开全文
  • 阅读本文之前请阅读:Python真正多线程之殇——GIL全局解释锁 https://blog.csdn.net/weixin_41827162/article/details/84563235  - 1. 认识线程同步现象: 在...

    阅读本文之前请阅读:Python真正多线程之殇——GIL全局解释锁 https://blog.csdn.net/weixin_41827162/article/details/84563235 

    -

    1. 认识线程同步现象:

    https://blog.csdn.net/weixin_41827162/article/details/84104421线程异步中,

    将方法1中:

    建多个线程,同时执行多个线程,由新到旧逐个释放线程

    改成:

    创建一个线程,执行一个线程,释放一个线程

    -

    #!/usr/bin/python3
    # 线程异步
     
    import threading
    import time
     
    exitFlag = 0
     
     
    class myThread(threading.Thread):
        def __init__(self, thread_id, name, counter):
            threading.Thread.__init__(self)
            self.thread_id = thread_id
            self.name = name
            self.counter = counter
            pass
     
        def run(self):
            print("开始线程=" + self.name)
            run_def(self.name, self.counter, 5)
            print("退出线程=" + self.name)
            pass
        pass
     
     
    def run_def(thread_name, delay, counter):
        while counter:
            if exitFlag:
                thread_name.exit()
                pass
            time.sleep(delay)
            # time.sleep(0)
            list(thread_name)
            counter -= 1
            pass
        pass
     
     
    def list(thread_name):
        print("\n执行线程=" + thread_name)
        pass
     
     
    threads = []  # 存储在线线程
     
    # 创建线程
    for this_t in range(1, 10):
        t = myThread(this_t, "Thread-" + str(this_t), 0.1)
        t.start()
        t.join()  # 线程同步,线程异步
        threads.append(t)
        pass
     
    # 终止线程
    # for t in threads:
    #     t.join()
    #     pass
     
    print("程序完成!!")

    -

    2. 真正的线程同步:

    #!/usr/bin/python3
    
    # 线程同步
    
    import threading
    import time
    
    
    class myThread(threading.Thread):
        def __init__(self, threadID, name, counter):
            threading.Thread.__init__(self)
            self.threadID = threadID
            self.name = name
            self.counter = counter
    
        def run(self):
            print("开启线程: " + self.name)
            # 获取锁,用于线程同步
            threadLock.acquire()
            print_time(self.name, self.counter, 3)
            # 释放锁,开启下一个线程
            threadLock.release()
    
    
    def print_time(threadName, delay, counter):
        while counter:
            time.sleep(0)
            print("%s: %s" % (threadName, time.ctime(time.time())))
            counter -= 1
    
    
    threadLock = threading.Lock()
    threads = []
    
    
    for cal in range(1, 100):
        that = myThread(cal, "Thread-" + str(cal), cal).start()
        print("创建了线程=" + str(cal))
        threads.append(that)
        pass
    
    print("退出主线程")

    -

    展开全文
  • python多线程

    2018-03-05 22:04:17
    一. python的线程多线程多线程可以共享本进程...对于python多线程实现,其实只是一个线程在跑,不断地进行切换,不是真正多线程,即使遇到多核cpu,多核cpu只有一个核区发挥其作用,因此,python多线程用于...

    一. python的线程

    多线程:多线程可以共享本进程中的数据,但是不稳定,如果服务器用多线程来处理可能会因为其中一个线程崩了,而服务器就挂了,相反,多进程一般一个子进程错误,不会导致所有子进程都错误,但是主进程挂了,其他照样都挂。

    对于python的多线程实现,其实只是一个线程在跑,不断地进行切换,不是真正的多线程,即使遇到多核cpu,多核cpu只有一个核区发挥其作用,因此,python的多线程用于io密集型的操作中,而在cpu密集型的程序,反而变得更慢。

    起因为GIL:

    GILIn CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)

    之所以有GIL这个大坑主要是因为线程安全,python在多线程中为了使其能够实现线程安全,提高其性能,即在多线程下,不会对全局变量或者静态变量进行污染。通过这样的一个锁,使拥有GIL的线程才能运行,在提高性能的同时,效率却下降了,这是Python在效率和性能间的权衡。

    可能出现的问题:

    1. Python中释放GIL会触发操作系统的一次线程调度,激起后的线程等待被分配GIL,但是,再多核CPU中,如果该线程在其他核心,因为release gil和acquire gil之间的间隙可以说是很短的,大部分情况下很可能刚释放GIL的线程又再次得到GIL。

    2. 而这样,被唤醒的线程只能等待,这也一定程度上影响了IO线程(接收到消息时,有一个CPU密集型的线程仍在不断的释放,再次得到GIL)。此外,Python的线程安全并不是绝对安全,怎么感觉GIL还是没什么用,有时候还是会出错,如下面程序:

    import threading
    import time
    
    t_obj = []
    lock = threading.Lock()
    num = 0
    def run():
        global num
        #lock.acquire() 
        num += 1
        time.sleep(1)     
        num += 1   
        #lock.release()
    
    for i in range(100):
        t = threading.Thread(target = run)
        t_obj.append(t)
        t.start()
    
    for i in t_obj:
        t.join()
    
    print(num)

    可以发现,有时候跑出来的结果比正常值小,解决方法是用Python的一个互斥锁(线程锁),这样GIL的意义我就不太清楚是什么

    只有lock释放的时候,另外一个线程才能启动。出现结果为198的原因如下:


    PythonGIL释放算法是基于pcode(通过计算线程执行的微代码数量来进行GIL的切换),还是基于时间的切换。都有一个可能,程序在运行一半时被强行切换,此时Python将其数据暂时保存在缓冲区中,去执行另外一个线程,而没来得及数据的更新,另一个线程取的数据是没有++过的,而两个线程结果返回到内存时,其实可以说只进行了一次操作。(这里有一个猜想,可能被中途中断保存到缓冲区的线程的优先级比较高,不然的话结果可能偏差很大)

     

     

    其实CPYTHON中已经有了一个pthread线程调度算法,这是c语言自己的一个线程调用机制,应该可以理解为GIL是在pthread的上层对其进行管理。

    解决方法:

    1. 改进Reworking the GIL
    – 将切换颗粒度从基于opcode计数改成基于时间片计数(不知道其作用在哪)
    – 避免最近一次释放GIL锁的线程再次被立即调度
    – 新增线程优先级功能(高优先级线程可以迫使其他线程释放所持有的GIL锁)

    2. multiprocess替代Thread缺点为数据共享时将很浪费资源,要通过一个pickle

    3. 用其他解析器,其他解析器有的虽然不用GIL,但是其不是用c语言写的,c语言多模块的优势就体现不了(暂时无体会)

     

    出处:

    1.https://www.zhihu.com/question/23474039 Python多线程的妥协

    2.http://blog.csdn.net/q_l_s/article/details/51538039 IO密集型与CPU密集型,多线程与多进程

    3.https://www.zhihu.com/question/21486706 余天升 编译性语言和解释性语言

    4.http://python.jobbole.com/81822/    GIL(重点)

    5.https://wiki.python.org/moin/GlobalInterpreterLock (英)GIL

     

    展开全文
  • Python多线程

    2019-09-29 20:40:11
    线程是操作系统直接支持的执行单元,天赐高级预压通常都是内置多线程的支持,Python的线程是真正的POSIXThread而不是模拟出来的线程。 2、Python的标准库提供两个模块:thread与threading,thread是第几...

    Python之多线程

    一、概念
    1、多任务可以由多进程完成,也可以由一个进程内的多线程完成。
    进程是由若干的线程组成,一个进程至少有一个进程。
    线程是操作系统直接支持的执行单元,天赐高级预压通常都是内置多线程的支持,Python的线程是真正的POSIX Thread而不是模拟出来的线程。
    2、Python的标准库提供两个模块:thread与threading,thread是第几模块,threading是高级模块,对thread的封装,绝大多数的情况下只需要使用threading这个高级模块。
    3、启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行。
     
    二、实操
    eg:
    import threading
     
    def foo():
        pass
     
    t=threading.Thread(target=foo)
    t.start()
    t.join()
    print('this is main thread')
    

      

    任何进程默认情况就会启动一个线程,把该线程称为主线程,主线程又可以启动新的线程。
     
    threading.current_thread()永远返回当前线程的实例。主线程的名字为MainThread,子线程的名字在创建时指定,用LoopThread命名子线程,名字仅仅是在打印的时候会显示。
     
    三、Lock
    多线程和进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每一个进程中,互不影响,而多线程中满所有变量都是由所有线程共享。任何一个变量都可以被任何一个线程修改,因此线程之间的共享数据最大的危险在于多线程同时改一个变量,把内容容易改乱,或者出现资源抢占的问题。
     
    threading.Lock()为线程上锁,不会造成修改冲突。
    threading.acquire()解锁,其他线程即可获得资源。
    一般使用try finally来确保一定使用完后释放锁。
     
    四、多核CPU
    虽然Python是真的多线程,但是Python的解释器执行代码的时候有一个GIL锁,任何Python线程执行前,都必须先获得GIL锁,每执行100条字节码,解释器就自动的释放GIL锁,让别的线程有机会执行。
    五、ThreadLocal
    使用全局变量在方法中使用ThreadLocal对象,每个Thread对它都可以读写属性,但是互不影响。
    ThreadLocal最常用的地方就是胃每个线程绑定一个数据库连接。HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便的访问这些资源。
     
    eg:
    import threading
     
    local_school=threading.local()#创建全局的ThreadLocal对象
     
    def st1():
        print('%s (in %s)'%(local_school.student, threading.current_thread(),name))
     
    def st2(name):
        #绑定ThreadLocal的st1
    local_school.st1=name
    st1()
     
    t1=threading.Thread(target=st2,args=('A1'),name='Thread-A')
    t2=threading.Thread(target=st2,args=('B1'),name='Thread-B')
    t1.start()
    t2.start()
    t1.join()
    t2.join()
     
     
    

      

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     

    转载于:https://www.cnblogs.com/lsb123/p/11320823.html

    展开全文
  • 这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。 GIL是Python解释器设计的历史遗留问题,通常我们用的解释器是官方实现...
  • 阅读本文之前请阅读:Python真正多线程之殇——GIL全局解释锁 https://blog.csdn.net/weixin_41827162/article/details/84563235  - python3有threading和_thread两种线程写法,推荐使用threading。 开多线程...
  • Python——多线程

    2019-08-26 19:17:16
    由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。 Python的标准库提供了两个模块:_thread和...
  • python多进程和多线程的区别:python多线程不是真正意义上的多线程,由于python编译器的问题,导致python多线程存在一个PIL锁,使得python多线程的CPU利用率比预期的要低很多python的多进程(java的应该也是)...
  • python多线程

    2018-08-16 15:32:42
    注:本文是廖大的教程文章,本人也在学习,因为老是...由于线程是操作系统直接支持的单元,因此,高级语言都内置多线程的支持,python 也不例外,并且,python 的线程是真正的 Posix Thread ,不是模拟出来的线程。 ...
  • python:多线程

    2018-12-03 11:14:14
    线程是进程中的一个实体,是被系统独立调度和分派的...由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix(移植性操作系统接口) Thr...
  • python多线程

    2017-06-22 22:53:00
    Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核。多线程的并发在Python中就是一个美丽的梦。 Python的线程是真正的Posix Thread,而不是模拟出来的线程 Python的标准库提供了两个模块:_thread和...
  • python进行多线程计算

    2017-08-03 17:31:30
    python多线程不是真正多线程,因此我们可以使用多进程进行编程。http://blog.csdn.net/izzzyx/article/details/54601624
  • Python多线程

    2018-08-07 20:14:00
    据廖雪峰老师的学习文档介绍,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。 Python的标准库提供了两个模块:_thread和threading,_thread是...
  • 虽然python多线程受GIL限制,并不是真正多线程,但是对于I/O密集型计算还是能明显提高效率,比如说爬虫。 下面用一个实例来验证多线程的效率。代码只涉及页面获取,并没有解析出来。 # -*-coding:utf-8 -*- ...
  • Python 中的多线程 什么是线程 ​ 一个进程中包括多个线程,线程是 CPU 调度和分派的基本单位,是进程中执行运算的最小单位,真正在 CPU 上运行的是线程,可以与同一个进程中的其他线程共享进程的全部资源 Python ...
  • Python多线程效率低,原因在于Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL...
  • 线程是cpu执行的最小单元,因此一个进程中至少有一个线程。当我们在处理任务时,是依靠线程进行的,多线程和多进程意味着要同时处理多个任务。... 在python中,线程和进程之间最大的不同在于,多线程没法利...
  • python学习笔记,特做...由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。 Python的标准库提供...
  • python-多线程

    2019-02-14 16:42:58
    (1)一个线程只能属于一个进程,而一个进程可以有线程,但至少有一个线程。 (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。 (3)CPU分给线程,即真正在CPU上运行的是线程。   并行处理...
  • 廖雪峰python-多线程

    2020-11-11 14:44:48
    由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。Python的标准库提供了两个模块:thread和...
  • 虽然python多线程受GIL限制,并不是真正多线程,但是对于I/O密集型计算还是能明显提高效率,比如说爬虫。分别用两种方式获取10个访问速度比较慢的网页,一般方式耗时50s,多线s。序:叮咚叮咚,...
  • 今天简单测试了下python中的多线程与协程,之前在看python的教程中有说到python多线程其实是在一个线程中来回切换并不会真正的去使用多核资源。如果想真正去利用多核资源,最好的办法是使用python的多进程+协程的...
  • python中,由于GIL(Global Interpreter Lock)全局解释器锁的存在,所以多线程并不是真正意义上的多线程。在 Python 语言的主流实现 CPython 中,GIL 是一个货真价实的全局线程锁,在解释器解释执行任何 Python ...
  • python实现真正多线程

    千次阅读 2020-06-16 23:26:00
    Python代码中有一个threading模块,可以创建多线程,但是在这种模式下创建的多线程并不能将多核利用起来,所有由这种模式下创建的线程最多只能共享一个CPU核,所以在有些场景下,需要将一个作业分配给一个独立的线程...
  • 虽然python多线程受GIL限制,并不是真正多线程,但是对于I/O密集型计算还是能明显提高效率,比如说爬虫。分别用两种方式获取10个访问速度比较慢的网页,一般方式耗时50s,多线s。序:叮咚叮咚,...
  • 但长期以来,Python最为人诟病的就是它有一把锁:GIL,这把锁让Python无法真正的实现多线程执行,无法利用多核CPU的高性能。(但是可以多进程) GIL(Global Interpreter Lock)全局解释器锁 In short, Python...
  • python多线程

    2018-12-22 15:11:15
    python中,多进程是可以利用多核进行真正并行的,但是多线程就不行了,理由可以参考这篇文章python学习笔记- day10-4【问题:为什么python多线程不能利用多核CPU?】,标题一和标题三都总结得很好。   一,...
  • 由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。 Python的标准库提供了两个模块:_thread和...
  • Python多线程

    2019-09-30 12:30:31
    因为Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global...这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用...
  • python多线程问题

    2013-11-29 18:43:00
    在对文件进行预处理的时候,由于有的文件有太大,处理很...使用multiprocessing模块实现真正的并发 因为GIL会序列化线程, Python中的多线程不能在多核机器和集群中加速. 因此Python提供了multiprocessing模块, 可以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 883
精华内容 353
关键字:

python真正多线程

python 订阅