-wenli

python多线程threading

 

目录

 

threading介绍与简单使用

join功能

queue功能

lock锁

 

 

threading介绍与简单使用

 

threading介绍:

threading模块


threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。



除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:
run(): 用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
isAlive(): 返回线程是否活动的。
getName(): 返回线程名。
setName(): 设置线程名。

  

 

程序示例:import threading


import threading

def thread_job():

print("this is an added Thread ,number is %s" %threading.currentThread())


def main():
added_thread = threading.Thread(target=thread_job) # 定义一个新的线程,指定一个任务给target
added_thread.start() # 开启线程
print(threading.activeCount())
print(threading.enumerate())
print(threading.currentThread())


if __name__ =='__main__':
main()


  

 

 程序运行结果

 

 

第一个输出是当前线程,这个是我们开启的线程

第二个输出的是在正在运行的线程的数量

第三个输出返回一个包含正在运行的线程的list,包含主线程和开启的线程

第四个输出是当前线程,最后只剩下主线程

 

 

 

join功能

 

join功能介绍

join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。

当我们有一个程序功能必须等到开启的线程执行完以后,才能运行主线程,就可以使用这个功能。

 

不加join的情况,这种情况下,以下例程序看来,主线程运行更快,我们看看结果

程序示例1:

import threading
import time


def thread_job():

   print("T1 start")
   for i in range(10):
       time.sleep(0.1)
   print("T1 finish")


def main():
   added_thread = threading.Thread(target=thread_job,name = 'T1') #定义一个新的线程,指定一个任务给target
   added_thread.start()  #开启线程
   print("all done")

  

if__name__=='__main__':
   main()

  

 

程序运行结果

 

 

 

 

加join的情况,等待我们开启的线程执行完以后才能运行主线程。

程序示例2:

import threading
import time


def thread_job():

   print("T1 start")
   for i in range(10):
       time.sleep(0.1)
   print("T1 finish")


def main():
   added_thread = threading.Thread(target=thread_job,name = 'T1') #定义一个新的线程,指定一个任务给target
   added_thread.start()  #开启线程
   added_thread.join()
   print("all done")


if __name__ == '__main__':
    main()

 

 

程序运行结果

 

 

 

 

 

queue功能

 

queue功能:

线程优先级队列( Queue)
Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列 PriorityQueue。
这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。
Queue 模块中的常用方法:
Queue.qsize() 返回队列的大小
Queue.empty() 如果队列为空,返回True,反之False
Queue.full() 如果队列满了,返回True,反之False
Queue.full 与 maxsize 大小对应
Queue.get([block[, timeout]])获取队列,timeout等待时间
Queue.get_nowait() 相当Queue.get(False)
Queue.put(item) 写入队列,timeout等待时间
Queue.put_nowait(item) 相当Queue.put(item, False)
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作

 

 

下面只演示了在多线程中怎么返回线程中的运行结果,因为不能使用return返回! 使用Queue.get()和Queue.put()方法

程序示例

import threading
from queue import Queue


def job(l,q):
    for i in range(len(l)):
        l[i] = l[i] + 1  # 对列表里每一个值加一
    q.put(l)  # 把计算的结果保存到queue


def main():
    q = Queue()  # 使用queue存放返回值
    threads = []  # 创建进程列表

    data = [[1, 2], [3, 4], [4, 5], [5, 6]]

    # 创建四个进程并启动添加到进程列表里面
    for i in range(4):
        t = threading.Thread(target=job, args=(data[i], q))
        t.start()
        threads.append(t)

    # 把所有线程都加到主线程中
    for thread in threads:
        thread.join()

    # 创建存放结果的列表
    results = []

    # 把结果保存到results列表中
    for _ in range(4):
        results.append(q.get())
    print(results)
    
    


if __name__ =='__main__':
    main()

  

 

 程序运行结果

 

 

 

比较多线程和不使用多线程的运行速度

我们知道python中实现多线程其实是把正在运行的线程锁住,这时候其他线程就不会运行,就是在同一时间里只有一个线程在运行,在不断地切换线程中就可以实现多线程。

下面我使用多线程和不使用线程,来做同样的运算工作,看谁运行的更快。

 

import threading
from queue import Queue
import time


def job(l,q):
    for i in range(len(l)):
        l[i] = l[i] + 1  # 对列表里每一个值加一
    q.put(l)  # 把计算的结果保存到queue


def normal(l):
    results = []
    for i in range(len(l)):
        l[i] = l[i] + 1
        results.append(l[i])
    return results




def main(list):
    q = Queue()  # 使用queue存放返回值
    threads = []  # 创建进程列表

    # 创建四个进程并启动添加到进程列表里面
    for i in range(4):
        t = threading.Thread(target=job, args=(list[i], q))
        t.start()
        threads.append(t)

        # 把所有线程都加到主线程中
    for thread in threads:
        thread.join()

        # 创建存放结果的列表
    results = []

    # 把结果保存到results列表中
    for _ in range(4):
        results.append(q.get())
    print(results)




if __name__ =='__main__':
    data1 = [[1, 2], [3, 4], [4, 5], [5, 6]]
    data2 = [[1, 2], [3, 4], [4, 5], [5, 6]]

    start1_time =time.time()
    main(data1)
    print(time.time()-start1_time)

    start2_time = time.time()
    result = []
    for i in range(len(data2)):
      result.append(normal(data2[i]))
        
    print(result)
    print(time.time()-start2_time)

  

运行结果

在pycham和网上的在线编译器上都运行过,大致上来多线程运行的速度要快不少

 

 

 

 

 

 

 

lock锁

 

 

lock锁:

当多个线程同时运行,比如一个线程接收信息,另一个线程处理信息,功能就是需要接收信息的线程执行完,才能执行另一处理信息的线程,就可以使用这个功能。

lock.acquire() 锁住
lock.release() 解锁

 

程序示例


import threading


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

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



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

  

 

程序运行结果

 

分类:

python

技术点:

相关文章: