什么是线程?
线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。(摘自百度百科)线程之间的资源是共享的
什么是多线程?
多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能(摘自百度百科)
如何理解多线程?
多进程相当于我们的电脑既开浏览器,又开音乐播放器。而多线程相当于在音乐播放器里所进行的一些操作,如切歌、暂停等。
如何实现多线程
python的多线程有两个模块来实现:thread
和threading
,thread模块用的很少,更偏向于底层操作。我们一般都用threading模块进行操作。
下面是我用py2.7写的一个小Demo,用来大致分析多线程的实现和作用。
# -*- coding: UTF-8 -*-
import threading
num = 1
def print_num(thread_name,num):
while num<=20:
print "%s:%d"%(thread_name,num)
num+=1
try:
t1 = threading.Thread(target=print_num,args=("Thread1",num))
t2 = threading.Thread(target=print_num,args=("Thread2",num))
t1.start()#开始线程1
t2.start()#开始线程2
except:
print "something error!"
创建多线程所需要用到的函数为threading.Thread()
。其中target参数即为需要多线程执行的函数名,args参数为执行函数所需要传入的参数
然后用start()
来开始执行。
我们来看看运行结果:
可以看到,虽然线程1、2的启动时间差了一点,但仍可以看到有一段时间内两个线程共同运行了函数print_num
,平时需要运行两次函数需要在上一次函数运行完成后才能进行下一次调用,而多线程可以让他们同时进行。如果想它同时对num
进行运算,只需要将num
变量设置为全局变量即可。
什么是守护进程
对上个实验而言,主线程会在等待这两个子线程结束之后才会结束。如果想让主线程直接结束,可以利用setDaemon(True)
在子线程开始之前设置为守护进程,如下面:
# -*- coding: UTF-8 -*-
import threading
num1 = 1
def print_num(thread_name):
global num1
while num1<=1000://注意这里的停止范围
num1 += 1
print thread_name+":"+str(num1)
try:
t1 = threading.Thread(target=print_num,args=("Thread1",))
t2 = threading.Thread(target=print_num,args=("Thread2",))
t1.setDaemon(True)//设置守护进程
t2.setDaemon(True)
t1.start()
t2.start()
except:
print "something error!"
结果为:
可以看到,虽然我设置num1加到1000结束,但实际上num加到18就结束了。
什么是互斥锁?有什么用?
前面提到线程之间的资源是共用的,这就造成了一个问题:多个线程同时修改同一条数据时可能会出现脏数据。举个例子:
现在有两个线程t1、t2和一个全局变量a,t1和t2同时对a进行+1-1操作。看起来a似乎一直都没有变化,但当t1和t2同时进行到+的操作时,a的值有时会变成3,此时如果要使用a的数据就可能出现问题。
此时,我们就需要互斥锁,当t1对a进行操作的时候锁住,让t2不能修改a,等t1操作完之后再释放锁
代码如下:
# -*- coding: UTF-8 -*-
import threading
num1 = 1
lock = threading.Lock()
def print_num(thread_name):
global num1
while True:
num1+=1
num1-=1
if num1 == 3:
print thread_name+":"+str(num1)
exit(0)
def run_thread(thread_name):
lock.acquire()//获取锁
try:
print_num(thread_name)
finally:
lock.release()//释放锁
try:
t1 = threading.Thread(target=run_thread,args=("Thread1",))
t2 = threading.Thread(target=run_thread,args=("Thread2",))
t1.start()
t2.start()
except:
print "something error!"
此时再运行就没有这个问题了。
递归锁和异步还没有看完,以后再更新
参考文章:
https://www.liaoxuefeng.com/wiki/1016959663602400/1017629247922688