Python通过两个标准库thread和threading提供对线程的支持。thread提供了低级别的、原始的线程以及一个简单的锁。threading模块对thread进行了进一步的封装,因此在使用的时候,一般使用threading模块。

多任务可以由多进程完成,也可以由一个进程内的多线程完成。进程是由若干线程组成的,一个进程至少有一个线程。

1、使用threading模块创建线程

例:利用Thread类创建线程




python多进程 共享int 参数 python多进程共享全局变量_python全局变量

创建线程




python多进程 共享int 参数 python多进程共享全局变量_python多进程 共享int 参数_02

创建线程运行结果



与利用Process()创建进程类似,Thread()类的target函数接受一个函数,用于Thread类执行时调用,如果调用的函数需要参数,则通过args参数传递一个元组类型的参数列表。

例:调用带参数的函数




python多进程 共享int 参数 python多进程共享全局变量_python定义全局变量_03

Thread调用带参数的函数




python多进程 共享int 参数 python多进程共享全局变量_python 判断线程状态_04

Thread调用带参数的函数运行结果



当需要一些复杂的逻辑时,直接用Thread()调用函数总显得有些复杂,我们可以利用Thread创建的子类满足需求。

2、使用Thread子类创建线程

例:利用Thread子类创建线程




python多进程 共享int 参数 python多进程共享全局变量_python 判断线程状态_05

利用Thread子类创建线程




python多进程 共享int 参数 python多进程共享全局变量_python全局变量_06

利用Thread子类创建线程运行结果



我们自己创建的类,继承自Thread,当执行start()方法时,Python解释器会调用自定义类中重写的run()方法。

3、多个线程的执行顺序

当启动多个线程时,线程之间的执行是没有顺序的,线程之间的调度是由操作系统的调度算法来决定的。

例:启动多个线程




python多进程 共享int 参数 python多进程共享全局变量_python全局变量_07

启动多个线程




python多进程 共享int 参数 python多进程共享全局变量_python 全局变量_08

多个线程执行是无序的



4、多个线程之间共享全局变量

多个进程之间是相互独立的,因此多个进程之间是不会共享全局变量的。但是多个线程之间会共享全局变量,当一个线程改变全局变量时,另一个线程中的全局变量会随之改变。

例:多线程之间共享全局变量




python多进程 共享int 参数 python多进程共享全局变量_python 全局变量_09

多线程共享全局变量




python多进程 共享int 参数 python多进程共享全局变量_python 判断线程状态_10

多线程共享全局变量运行结果



5、多个线程共享全局变量造成的问题

多个线程共享全局变量的优点是,不再像多个进程那样,如果要共享数据需要借助第三方才能够实现,比如Queue,但是如果处理不好多线程共享全局变量,会发生意想不到的结果。

例:多个线程共享全局变量造成的问题




python多进程 共享int 参数 python多进程共享全局变量_python全局变量_11


python多进程 共享int 参数 python多进程共享全局变量_python 判断线程状态_12


python多进程 共享int 参数 python多进程共享全局变量_python全局变量_13


python多进程 共享int 参数 python多进程共享全局变量_python多进程 共享int 参数_14


6、解决多线程共享全局变量BUG

我们可以定义另一个全局变量,来判断当前线程的状态,只有当一个线程执行完之后,另一个线程才能开启。

例:定义线程是否执行完标记


python多进程 共享int 参数 python多进程共享全局变量_python全局变量_15

定义判断线程是否结束标记


python多进程 共享int 参数 python多进程共享全局变量_python多进程 共享int 参数_16

运行结果


由以上程序可知,定义了判断线程结束标记以后,虽然能够解决问题,但是当第一个线程执行时,第二个线程在循环判断标记是否已经改变,循环判断会占用CPU资源,对性能造成影响。

7、利用互斥锁

某个线程要共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进入写入操作,从而保证了多线程情况下数据的正确性。

创建锁

mutex=threading.Lock()

锁定

mutex.acquire([blocking])#里面可以加blocking(等待的时间)或者不加,不加就会一直等待(堵塞)

释放

mutex.release()


python多进程 共享int 参数 python多进程共享全局变量_python定义全局变量_17

利用互斥锁解决共享全局变量问题


python多进程 共享int 参数 python多进程共享全局变量_python 全局变量_18

运行结果


只要一上锁,由多任务变为单任务,相当于只有一个线程在运行。