最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • python如何实现多线程

    正文概述    2020-01-16   267

    python如何实现多线程

    python实现多线程的方法:

    1、Thread直接创建子线程

    首先可以使用 Thread 类来创建一个线程,创建时需要指定 target 参数为运行的方法名称,如果被调用的方法需要传入额外的参数,则可以通过 Thread 的 args 参数来指定。

    import threading
    import time
    def target(second):
        print(f'Threading {threading.current_thread().name} is running')
        print(f'Threading {threading.current_thread().name} sleep {second}s')
        time.sleep(second)
        print(f'Threading {threading.current_thread().name} is ended')
    print(f'Threading {threading.current_thread().name} is running')
    for i in [1, 5]:
        thread = threading.Thread(target=target, args=[i])
        thread.start()
        
    print(f'Threading {threading.current_thread().name} is ended')

    运行结果:

    Threading MainThread is running
    Threading Thread-1 is running
    Threading Thread-1 sleep 1s
    Threading Thread-2 is running
    Threading Thread-2 sleep 5s
    Threading MainThread is ended
    Threading Thread-1 is ended
    Threading Thread-2 is ended

    如果想要主线程等待子线程运行完毕之后才退出,可以让每个子线程对象都调用下 join 方法:

    threads = []
    for i in [1, 5]:
        thread = threading.Thread(target=target, args=[i])
        threads.append(thread)
        thread.start()
        
    for thread in threads:
        thread.join()

    运行结果:

    Threading MainThread is running
    Threading Thread-1 is running
    Threading Thread-1 sleep 1s
    Threading Thread-2 is running
    Threading Thread-2 sleep 5s
    Threading Thread-1 is ended
    Threading Thread-2 is ended
    Threading MainThread is ended

    2、继承Thread类创建子线程

    另外也可以通过继承 Thread 类的方式创建一个线程,该线程需要执行的方法写在类的 run 方法里面即可。上面的例子的等价改写为:

    import threading
    import time
    class MyThread(threading.Thread):
        def __init__(self, second):
            threading.Thread.__init__(self)
            self.second = second
        
        def run(self):
            print(f'Threading {threading.current_thread().name} is running')
            print(f'Threading {threading.current_thread().name} sleep {self.second}s')
            time.sleep(self.second)
            print(f'Threading {threading.current_thread().name} is ended')
    print(f'Threading {threading.current_thread().name} is running')
    threads = []
    for i in [1, 5]:
        thread = MyThread(i)
        threads.append(thread)
        thread.start()
        
    for thread in threads:
        thread.join()
        
    print(f'Threading {threading.current_thread().name} is ended')

    运行结果:

    Threading MainThread is running
    Threading Thread-1 is running 
    Threading Thread-1 sleep 1s 
    Threading Thread-2 is running 
    Threading Thread-2 sleep 5s 
    Threading Thread-1 is ended 
    Threading Thread-2 is ended 
    Threading MainThread is ended

    守护线程

    在线程中有一个叫作守护线程的概念,如果一个线程被设置为守护线程,那么意味着这个线程是“不重要”的,这意味着,如果主线程结束了而该守护线程还没有运行完,那么它将会被强制结束。

    在 Python 中我们可以通过 setDaemon 方法来将某个线程设置为守护线程:

    import threading
    import time
    def target(second):
        print(f'Threading {threading.current_thread().name} is running')
        print(f'Threading {threading.current_thread().name} sleep {second}s')
        time.sleep(second)
        print(f'Threading {threading.current_thread().name} is ended')
    print(f'Threading {threading.current_thread().name} is running')
    t1 = threading.Thread(target=target, args=[2])
    t1.start()
    t2 = threading.Thread(target=target, args=[5])
    t2.setDaemon(True)
    t2.start()
    print(f'Threading {threading.current_thread().name} is ended')

    运行结果:

    Threading MainThread is running 
    Threading Thread-1 is running 
    Threading Thread-1 sleep 2s 
    Threading Thread-2 is running 
    Threading Thread-2 sleep 5s 
    Threading MainThread is ended 
    Threading Thread-1 is ended

    互斥锁

    在一个进程中的多个线程是共享资源的,比如在一个进程中,有一个全局变量 count 用来计数,现在声明多个线程,每个线程运行时都给 count 加 1,代码实现如下:

    import threading
    import time
    count = 0
    class MyThread(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
        def run(self):
            global count
            temp = count + 1
            time.sleep(0.001)
            count = temp
    threads = []
    for _ in range(1000):
        thread = MyThread()
        thread.start()
        threads.append(thread)
    for thread in threads:
        thread.join()
        
    print(f'Final count: {count}')

    运行结果:

    Final count: 69

    由于 count 这个值是共享的,每个线程都可以在执行 temp = count 这行代码时拿到当前 count 的值,但是这些线程中的一些线程可能是并发或者并行执行的,这就导致不同的线程拿到的可能是同一个 count 值,最后导致有些线程的 count 的加 1 操作并没有生效,导致最后的结果偏小。

    所以,如果多个线程同时对某个数据进行读取或修改,就会出现不可预料的结果。为了避免这种情况,我们需要对多个线程进行同步,要实现同步,我们可以对需要操作的数据进行加锁保护,这里就需要用到 threading.Lock 了。

    加锁保护

    某个线程在对数据进行操作前,需要先加锁,这样其他的线程发现被加锁了之后,就无法继续向下执行,会一直等待锁被释放,只有加锁的线程把锁释放了,其他的线程才能继续加锁并对数据做修改,修改完了再释放锁。

    这样可以确保同一时间只有一个线程操作数据,多个线程不会再同时读取和修改同一个数据。

    更多Python知识,请关注:Python自学网!!


    下载网 » python如何实现多线程

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元