Ywc's blog

Python多线程

Word count: 1kReading time: 4 min
2020/02/01

多线程的使用

不错的文章

继承threading.Thread

继承threading.Thread模块是一个很好的一个选择,就像java中也是可以继承类和实现接口一样,这都是很好的选择

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import threading

class Mythread(threading.Thread):
def __init__(self,threadID,name,counter):
threading.Thread.__init__(self) #首先需要先保留原来threading.Thread中的初始化函数
self.threadID=threadID #重命名线程的ID
self.name=name #线程的名字
self.counter=counter #线程的数量
def run(self):
lock.acquire() #获取线程锁Lock
for i in range(10):
print "线程"+self.name+"开始运行"
lock.release() #释放线程锁Lock,这面也可以使用with lock: 来自动上锁和释放锁
if __name__ == '__main__':
lock=threading.Lock()
t1=Mythread(0,"thread-1",3)
t2=Mythread(1,"thread-2",3)
t1.start()
t2.start()
threads=[]
threads.append(t1)
threads.append(t2)
for t in threads:
t.join() #阻塞主线程,直至线程运行完毕才运行main线程的语句
print "线程运行结束"

这种继承的方式有一个缺点,这个和java中继承来实现多线程是一样的,就是一个对象只能是对应一个线程,并不能一个对象被多个线程共享

直接调用threading.Thread

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import threading
def func(name,age):
for i in range(10):
print name+"的年龄为:"+str(age)

t1=threading.Thread(target=func,args=["THR",22])
t2=threading.Thread(target=func,args=["YWC",21])
t1.start()
t2.start()
t1.join()
t2.join() # join方法的用途是:等待前一个线程结束,再执行下一个
import threading

def get_flag(flag):
for i in range(10):
print flag+"是真的"

t1=threading.Thread(target=get_flag,args=("Ywc",)) # 只有一个参数时,args处要加个逗号
t1.start()
t1.join()

Thread对象的相关方法

start() 启动线程
join([timeout]) 设置阻塞线程,timeout是可选的参数,表示阻塞的时间,如果没有就是当此线程运行结束才开始运行下一个线程
run() 线程活动的方法
getName() 获取线程名称
setName() 设置线程的名称
isAlive() 判断线程是否还活着
isDaemon() 判断是否是守护线程
setDaemon() 设置为守护线程,守护线程就是当主线程运行完后,这个线程也会随着主线程的结束而结束

解决的问题

Python中的多线程并不是真正地多个任务同步执行, 而是给每个任务分配一部分的执行时间, 轮流执行, 因此资源竞争的问题就会随之而来

队列Queue

队列的作用:
1、解耦:避免两者之间的过度依赖,以免其中一方出现问题,另一方不能再执行。
2、效率:增加数据处理的效率。

队列的方法

方法 用法说明
put 放数据,Queue.put( )默认有block=True和timeout两个参数。当block=True时,写入是阻塞式的,阻塞时间由timeout确定。当队列q被(其他线程)写满后,这段代码就会阻塞,直至其他线程取走数据。Queue.put()方法加上 block=False 的参数,即可解决这个隐蔽的问题。但要注意,非阻塞方式写队列,当队列满时会抛出 exception Queue.Full 的异常
get 取数据(默认阻塞),Queue.get([block[, timeout]])获取队列,timeout等待时间
empty 如果队列为空,返回True,反之False
qsize 显示队列中真实存在的元素长度
maxsize 最大支持的队列长度,使用时无括号
join 实际上意味着等到队列为空,再执行别的操作
task_done 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
full 如果队列满了,返回True,反之False

生产者和消费者模型

解决程序解耦,较少的资源解决高并发的问题

Reference

https://chenjiabing666.github.io/2017/09/03/%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%9A%84%E4%BD%BF%E7%94%A8/

CATALOG
  1. 1. 多线程的使用
    1. 1.1. 继承threading.Thread
    2. 1.2. 直接调用threading.Thread
    3. 1.3. Thread对象的相关方法
  2. 2.
    1. 2.1. 解决的问题
  3. 3. 队列Queue
  4. 4. 队列的方法
    1. 4.1. 生产者和消费者模型
  5. 5. Reference