Threading学会多线程Python

https://www.bilibili.com/video/BV1jW411Y7Wj?p=3&vd_source=d59d7bc22106d87da35c63b8af6491e8

文章目录

      • 什么是多线程?
      • 添加线程 add thread
      • join 功能
      • Queue 功能
      • 不一定有效率 GIL
      • 锁 lock

什么是多线程?

thread 可以让python在同一时间去做很多东西,大大节省了计算机计算的时间。

添加线程 add thread

import threading

def thread_job():
	print("This is an added Thread, number is %s" % threading.current_thread)	// 将当前线程的名称打印出来

def main():
	print(threading.active_count())	// 现在有多少个激活了的线程
	print(threading.enumerate())	// 具体是哪几个呢
	print(threading.current_thread())	// 当前线程
	
	added_thread = threading.Thread(target=thread_job)	// 添加一个线程,并给入任务
	added_thread.start()	// 真正执行线程


if __name__ == '__main__':
	main()
	

join 功能

import threading

def thread_job():
	print('T1 start\n')
	for i in range(10):
		time.sleep(0.1)
	print('T1 finish\n')

def main():
	added_thread = threading.Thread(target=thread_job, name='T1')	// 添加一个线程,并给入任务,命名线程名字为T1
	added_thread.start()	// 真正执行线程
	print('all done\n')


if __name__ == '__main__':
	main()

Threading学会多线程Python_第1张图片

多线程是同时在进行的一个线程任务
如果你想等待所有线程运行完之后,然后再开始其他命令,就会用到join

import threading

def thread_job():
	print('T1 start\n')
	for i in range(10):
		time.sleep(0.1)
	print('T1 finish\n')

def main():
	added_thread = threading.Thread(target=thread_job, name='T1')	// 添加一个线程,并给入任务,命名线程名字为T1
	added_thread.start()	// 真正执行线程
	added_thread.join()
	print('all done\n')


if __name__ == '__main__':
	main()

Threading学会多线程Python_第2张图片

import threading

def thread_job():
	print('T1 start\n')
	for i in range(10):
		time.sleep(0.1)
	print('T1 finish\n')


def T2_job():
	print('T2 start\n')
	print('T2 finish\n')


def main():
	added_thread = threading.Thread(target=thread_job, name='T1')	// 添加一个线程,并给入任务,命名线程名字为T1
	thread2 = threading.Thread(target=T2_job, name='T2')
	added_thread.start()	// 真正执行线程
	thread2.start()
	added_thread.join()
	print('all done\n')


if __name__ == '__main__':
	main()

假如没有join
Threading学会多线程Python_第3张图片
added_thread.join()
Threading学会多线程Python_第4张图片

thread2.join()
Threading学会多线程Python_第5张图片

thread2.join() && add_thread.join()
Threading学会多线程Python_第6张图片

Queue 功能

多线程所要摄取的功能是没有返回值的,所以我们要把它运算出来的结果放到一个长的队列中,对于每个线程的队列到了主线程再拿出来,进行计算。

import threading
import time 
from queue import Queue

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


def multithreading():
	q = Queue()
	threads = []
	data = [ [1, 2, 3], [3, 4, 5] , [4, 4, 4], [5, 5, 5] ]
	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 = []
	for _ in range(4):
		results.append(q.get())	// 从q中按顺序拿出一个
	print(results)	

if __name__ == '__main__'
	multithreading()

在这里插入图片描述

不一定有效率 GIL

多线程有个全局控制,并不是把任务平均分给每个人。
它其实是有个GIL(Global Interpreter Lock),全局解释器锁
为了实现多线程功能,其实是让程序把这个线程锁住,Python只能让一个线程在同一时间运算,其实是在不断切换,看似多线程

import threading
import time
import copy
from queue import Queue

def job(l, q):
    res = sum(l)
    q.put(res)

def multithreading(l):
    q = Queue()
    threads = []
    for i in range(4):
        t = threading.Thread(target=job, args=(copy.copy(l),q),name='T%i'%i)
        t.start()
        threads.append(t)
    [t.join() for t in threads]
    total = 0
    for _ in range(4):
        total += q.get()
    print(total)


def normal(l):
    total = sum(l)
    print(total)


if __name__ == '__main__':
    l = list(range(1000000))
    s_t=time.time()
    normal(l*4)
    print('normal:',time.time()-s_t)
    s_t=time.time()
    multithreading(l)
    print('multithreading:',time.time()-s_t)

Threading学会多线程Python_第7张图片
如果一个线程负责发送,另外一个线程负责接收,效率会提高很多。

如果是要处理数据,多线程可能帮不上我们的忙

python中因为GIL的存在,多线程适合IO密集型,多进程适合运算密集型

因为每一个核是有单独的逻辑的空间,不会受GIL的影响

锁 lock

如果你想第一个线程先处理完数据得到一个初步的结果,再拿去给第二个线程处理的话。
你可能要用到锁的功能,先锁住第一个线程,等它处理完,再运行第二个线程。

import threading

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


def job2():
	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()

你可能感兴趣的:(Python基础学习,python)