python多线程
文章目录
- python多线程
- 一、并发与并行?
- 二、同步与异步的概念?
- 三、线程与进程的区别?
- 需求1:多线程执行不同任务:
- 需求2:多线程执行相同任务:
- 1.threading并发性
- 2.多线程并发---资源共享,资源竞争问题:
一、并发与并行?
1、多任务概念:操作系统可以同时运行多个任务。
2、并发:任务数量多于cpu核数,通过操作系统的任务调度算法,多个任务可以一起执行,实际总有一些任务不在一起执行,因为切换任务的速度相当快。宏观上是一起执行,微观上不是一起执行的。
3、并行:指的是任务数量小于cpu核数,即任务真的是一起执行。
⚠️多线程都是并发的状态,缺点是比并行慢
二、同步与异步的概念?
1、同步:协同步调
def work():print("1")
def work2():print("2")
if __name__ == '__main__':work()work2()
2、异步:步调各异
三、线程与进程的区别?
1、线程被包含在进程内,一个程序启动时,先启动进程,进程调用线程执行任务。
2.线程依赖进程。
3.线程可以被抢占(中断)
需求1:多线程执行不同任务:
1、函数
函数式:调用thread模块中的start_new_thread()函数来产生新线程:
thread.start_new_thread ( function, args[, kwargs] )
参数说明:
function - 线程函数。
args - 传递给线程函数的参数,他必须是个tuple类型。
kwargs - 可选参数
示例1:主线程不等待子线程
import time
import threading as td#为线程定义一个函数def asr_test1(url):print("start")print(time.ctime(time.time()))def asr_test2(url):print("end")print(time.ctime(time.time()))if __name__ == '__main__':
#target为函数名,args为元组,函数一定要输入形参t1=td.Thread(target=asr_test1,args=("",))t2 = td.Thread(target=asr_test1, args=("",))t1.start()t2.start()
结果:
start
Fri Aug 5 16:03:05 2022
start
Fri Aug 5 16:03:05 2022
示例2、主线程等待子线程执行完毕
import threading as th
def work():print("1")
def work2():print("2")#原理:启动时会调用python进程,进程调用主线程。
if __name__ == '__main__':'''子线程启动'''start_time = time.time()t1=th.Thread(target=work)t2 = th.Thread(target=work2)t1.start()t2.start()#主线程不会等待# t1.join(5)#设置主线程等待子线程的执行时间end = time.time() - start_timeprint(end)
thread提供了低级别的、原始的线程以及一个简单的锁。
Thread类提供以下方法:
run(): 用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
isAlive(): 返回线程是否活动的。
getName(): 返回线程名。
setName(): 设置线程名。
2、类包装线程对象
需求2:多线程执行相同任务:
1.threading并发性
线程并发运行并共享内存。
代码如下(重写run方法,继承Thread类):
import time
from threading import Thread
'''
Thread其他初始化参数:
target:指定任务函数
name:指定线程分组
'''
class MyThread(Thread):def run(self):for i in range(100):time.sleep(0.1)print("请求第{}次".format(self.name,i))if __name__ == '__main__':for i in range(5):t=MyThread(name=f"线程{i+1}")t.start()
传递参数一:
def work(name,age):for i in range(5):# time.sleep(1)print("{}work1----{}---{}".format(name,i,age))if __name__ == '__main__':#给任务函数传递参数,方式一:args参数,里面是元组# t=Thread(target=work,args=("",))# t.start()#方式2:kargst2 = Thread(target=work, kwargs={"name":"wupig","age":18})t2.start()
传递参数:继承类
在这里插入代码片
2.多线程并发—资源共享,资源竞争问题:
1、无法并行,原因是python解释器有一把锁:GIL,在同一时间只能执行一个线程。多线程是并发执行的,经过python解释器后进行线程调度,线程切换机制:
1、线程执行遇到IO耗时操作(sleep,网络io,文件io),python解释器释放锁,进行线程切换,再次获取全局锁。
2、线程执行时间达到一定的阈值(面试)
解决方法一:加锁
解决方法二:队列
死锁案例:
需求:
1、并发读取本地文件。
2、并发获取url地址。
xxx.txt文件中有很多URL地址,需求多并发获取。
'''需求:并发读取txt中的URL地址'''
list_test=[]
filename="../../url.txt"
file=open(filename,"r")
#列表推导式
list_test=[i.strip("\n") for i in file]
def audio_test():while list_test:url=list_test.pop()print(url)def atest_thread(THREAD_MAX, Test_Script):#创建空列表thread_list = []for i in range(int(THREAD_MAX)):# print("**************",i)thread_name = 'thread-' + str(i)print("thread_name",thread_name)new_thread = threading.Thread(target=Test_Script, args="", name=thread_name)thread_list.append(new_thread)new_thread.start()for thread_obj in thread_list:#thread_obj.join:等待至线程中止thread_obj.join()if __name__ == '__main__':starttime=time.time()count = 10# THREAD_MAX=10atest_thread(count, audio_test)endtime=time.time()-starttimeprint(endtime)
占坑
这样只有一个线程执行。需要创建列表,将线程放入列表中,然后循环变量列表进行json。