Python多线程threading

介绍

在Python中,使用多线程multi-threading可以『同时』执行多个任务,比如你需要一个线程来复制读取信息,另一个线程来解析。为什么这里的同时要加引号呢,这是由于Python中GIL,也就是全局锁,看似同时执行多个任务,实际上是分布执行的,只不过各自完成不同的任务会提高工作效率。如果你不了解GIL,请看下图

实例教程

实例1

import threading

def job():
    info = "this is an added thread, which is %s" % threading.current_thread
    print(info)

def main():
    print(threading.active_count())
    print(threading.enumerate())
    #print(threading.current_thread())

    # 创建一个Thread对象,让他来复制job任务
    new_thread = threading.Thread(target=job)
    # 执行线程任务
    new_thread.start()
    print(threading.active_count())

if __name__ == '__main__':
    main()

运行结果:

1
[<_MainThread(MainThread, started 140637982934784)>]
this is an added thread, which is <function current_thread at 0x7fe8cd92d378>
2

解释一下:

  1. threading是线程模块,需要导入
  2. threading.active_count()方法会给出所有激活的线程数量
  3. threading.enumerate()方法会列举出存在的每一个线程
  4. threading.current_thread()方法会给出当前正在执行的线程
  5. 使用时需要先创建线程对象,并指定任务(target),然后用start方法来执行

实例2

import threading
import time

def job():
    print('T1 start\n')
    # 让任务延迟一下
    for i in range(10):
        time.sleep(0.1)
    print('T1 finish\n')

def job2():
    print('T2 start\n')
    # 任务不延迟
    print('T2 finish\n')

def main():
    thread1 = threading.Thread(target=job,name='T1')
    thread2 = threading.Thread(target=job2,name='T2')
    thread1.start()
    thread2.start()

    #thread1.join()

    print('all done')

if __name__ == '__main__':
    main()

运行结果:

T1 start

T2 start

T2 finish

all done
T1 finish

会发现all done并不是在最后执行的,怎么办呢?试试把join方法解除封(注)印(释),请看结果:

T1 start

T2 start

T2 finish

T1 finish

all done

解释一下:

  1. 多个线程是交叉进行的
  2. join方法可以用来等待该线程完成任务

实例3

import threading
from queue import Queue
import time

def job(l,q):
    for i in range(len(l)):
        l[i] = l[i]**2

    q.put(l)

def multithreading(data):
    q = Queue()
    threads = []
    THREAD_NUM = 4
    for i in range(THREAD_NUM):
        t = threading.Thread(target=job,args=(data[i],q))
        t.start()
        threads.append(t)
    for t in threads:
        t.join()
    results = []
    for _ in range(THREAD_NUM):
        results.append(q.get())

    print(results)

def unithreading(data):
    for i in range(len(data)):
        l = data[i]
        for j in range(len(l)):
            data[i][j] = data[i][j]**2

    print(data)

if __name__ == '__main__':
    data1 = [[1],[2,3],[4,5,6],[7,8,9,10]]
    data2 = [[1],[2,3],[4,5,6],[7,8,9,10]]
    time1 = time.clock()
    unithreading(data1)
    time2 = time.clock()
    multithreading(data2)
    time3 = time.clock()

    runtime_uni = time2 - time1
    runtime_multi = time3 - time2

    print("Runtime for unithreading is %s seconds." % runtime_uni)
    print("Runtime for multithreading is %s seconds." % runtime_multi)

运行结果:

[[1], [4, 9], [16, 25, 36], [49, 64, 81, 100]]
[[1], [4, 9], [16, 25, 36], [49, 64, 81, 100]]
Runtime for unithreading is 4.300000000000137e-05 seconds.
Runtime for multithreading is 0.001118000000000001 seconds.

解释一下:

  1. 这个例子主要是对比一下单线程是多线程的速度
  2. 这里演示了如何创建多个线程(此处为4个),并且分别执行任务
  3. 因为线程任务本身是没有return的,所以顺便学习一下队列queue的用法,以及put和get方法

实例4

import threading

def job1():
    global A
    #global A,lock
    #lock.acquire()
    for i in range(10):
        A += 1
        print('job1',A)
    #lock.release()

def job2():
    global A
    #global A,lock
    #lock.acquire()
    for i in range(10):
        A += 10
        print('job2',A)
    #lock.release()

if __name__ == '__main__':
    lock = threading.Lock()
    A = 0
    t1 = threading.Thread(target=job1)
    t2 = threading.Thread(target=job2)
    t1.start()
    t2.start()
    t1.join()
    t2.join()

运行结果:

job1job2  111

job1job2  1222

job1job2  2333

job1job2  3444

job1job2  4555

job1job2  5666

job1job2  6777

job1job2  7888

job1job2  8999

job1job2  100110

你会发现这打印得错乱了,这也是多个线程交替工作得原因,如果先想要规定一个线程工作的时候防止别的线程干扰,需要怎么做呢?试试使用lock(注释部分)吧,再运行一下:

job1 1
job1 2
job1 3
job1 4
job1 5
job1 6
job1 7
job1 8
job1 9
job1 10
job2 20
job2 30
job2 40
job2 50
job2 60
job2 70
job2 80
job2 90
job2 100
job2 110

解释一下:

  1. lock可以用来锁住一个线程,放置别的线程干扰它
  2. acquire方法和release方法分别是用来加锁和解锁的

最后

多线程的简单应用就到这里,我们最开始说过由于GIL,Python得多线程并不是真正的去同时执行多个任务,那么有没有办法弥补呢?有,那就是多进程!你一定听说过多核吧,下次再讲:)

原文地址:https://www.cnblogs.com/mrdoghead/p/12121416.html

时间: 2024-10-20 15:11:53

Python多线程threading的相关文章

Python 多线程threading模块

首先,我们在了解多线程时需要理解的就是什么是多线程,按照官方的解释就是:多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术. 在我自学到这里的时候,通过会在想进程和线程到底是有什么区别,我的理解就是: 进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,一个进程可以包含多个线程. 下面就以简单的例子来加强我们对python 线程的理解. 默认情况下,我们在没有启动线程的时候,可以看一下程序总的运行时间,应该是每个函数

python多线程-threading模块

threading 是我们常用的用于 python 多线程的模块,其功能更加丰富.下面我们就来开始学习这个模块. 同样的,我这里声明一样我使用的版本是 python2.7,不同版本直接可能存在差异. 老规矩,使用 help() 函数获取帮助文档,看看里面有什么内容. threading 模块中提供了一个 thread 的类,注意不要和 thread 模块搞混了,两者差别还是很大的.thread 这个类可以实例化一个对象,每个对象代表一个线程,可以调用其中的 run() 方法来开启一个线程的运行.

再看python多线程------threading模块

现在把关于多线程的能想到的需要注意的点记录一下: 关于threading模块: 1.关于 传参问题 如果调用的子线程函数需要传参,要在参数后面加一个","否则会抛参数异常的错误. 如下: 1 for i in xrange(5): 2 threads.append(threading.Thread(target=worker,args=(i,))) 2.关于join()阻塞 join()方法一旦被调用,这个线程就会被阻塞住,等其他线程执行完才执行自身.当我们在主线程A中,创建了n个子线

Python多线程threading用法

Python里面经常会用到多线程,即所有的方法在同一时间开始运行,而不是按顺序一个一 个运行.所用到的模块为threading,下面详解threading用法. 我们写三个方法,one.two.three并正常运行. 这里只截图了one()方法,two.three与one内容一样. 按下面图中的运行方式,三个函数是分别在不同时间运行的. 我们用threading使三个方法在同一时间运行   定义一个线程池并把要运行的线程都写到这个线程池列表里: threads= [] #定义一个线程池t1 =

[Python 多线程] threading.local类 (六)

在使用threading.local()之前,先了解一下局部变量和全局变量. 局部变量: import threading import time def worker(): x = 0 for i in range(100): time.sleep(0.0001) x += 1 print(threading.current_thread(),x) for i in range(10): threading.Thread(target=worker).start() 运行结果: <Thread

Python 多线程 threading

#!/usr/bin/python # -*- coding: utf-8 -*- __author__ = 'gaogd' ''' ### 多进程 import threading import time def run(num):     print 'Hi, I am thread %s..lalala' % num     time.sleep(1) for i in range(20):   t = threading.Thread(target=run, args=(i,))   t

python 多线程threading

上一篇说到thread模块,我们要自己解决线程锁.其实也没有什么啦.只是现在的人都比较懒,既然有高级封装的函数为什么要自己写. 所以就有了threading. 其实都一样啦. 来一个最简单的threading代码: 1 import threading #导入thrteading模块 2 3 def run(): #线程函数,打印线程名字和i的值 4 for i in range(100): 5 print(threading.current_thread().getName()+"------

python 多线程threading的使用

一.线程创建方法 1. 普通创建 import threading def run(name): for i in range(3): print(name) if __name__ == '__main__': t1 = threading.Thread(target=run, args=("t1",)) t2 = threading.Thread(target=run, args=("t2",)) t1.start() t2.start() ----------

Python多线程(threading)学习总结

注:此文除了例子和使用心得是自己写的,很多都是Python核心编程中的原文.原文文风应该能看出来,就不每个地方单独表明出处了. 线程(有时被称为轻量级进程)跟进程有些相似,不同的是,所有的线程运行在同一个进程中,共享相同的运行环境.它们可以想像成是在主进程或"主线程"中并行运行的"迷你进程". 线程有开始,顺序执行和结束三部分.它有一个自己的指令指针,记录自己运行到什么地方.线程的运行可能被抢占(中断),或暂时的被挂起(也叫睡眠),让其它的线程运行,这叫做让步.一个