python中的多线程,多线程编程python
理解多线程是多个任务同时运行的一种方式。例如,在一个循环中,每个循环都被视为一个任务。我们希望第二个周期可以在第一个周期结束之前开始,这样可以节省时间。
python中这种同时运行的目的是最大化CPU的计算能力,利用大量的等待时间。这也说明,如果程序花时间不是因为等待时间,而是因为任务多,也就是计算要花那么长时间,那么多线程是无法提高运行时间的。
有关多线程的更多信息,请参考以下资料。
廖雪峰教程知乎回答百度有很多解释,这里就不赘述了。
简单易用,先看下面这个函数。
导入时间
def myfun():
时间.睡眠(1)
a=1 1
打印(a)如果我们要运行这个函数10次,它的运行时间主要在于每次睡眠的秒,1 ^ 1的计算不会花太多时间。在这种情况下,可以使用多线程来提高效率。
我们来看看不使用多线程的耗时和使用多线程的耗时。
不要使用多线程
t=time.time()
for _ in范围(5):
myfun()
Print(time.time()-t)给出的结果是5.500000000001
下面我们用多线程。
从线程导入线程
for _ in范围(5):
th=线程(target=myfun)
Th.start()这样用多线程其实是可以的。你会发现大概需要1秒,5个2会同时出来,也就是说5个周期实际上几乎同时运行,5个1秒的等待时间同时进行,最后只等了1秒。
多线程只有两个步骤。
用Thread添加一个线程。这里,每个循环被视为一个新线程,一个线程执行一次myfun函数。用Start()启动这个线程,每个线程都需要显式打开才能运行。这样启动一个线程后,就可以继续运行后面的程序,也就是下一个循环,不用等它运行完(然后创建第二个线程,第三个线程在运行前启动……)。这里需要注意的是,多线程是放在循环中的,循环无法定义后,可以从外部变成多线程。
读者可能会注意到,不使用多线程时,时间是通过程序计算的,而使用多线程时则不是。这是因为计算时间,需要添加一些代码,不能展示多线程最简单的用法,所以先不要计算时间。接下来我们来说说join()的使用方法,计算时间。
Join使用线程的join()方法来表示程序将在线程完成运行后停止运行。让我们看看下面的例子。
从线程导入线程
t=time.time()
for _ in范围(5):
th=线程(target=myfun)
th.start()
th.join()
print(time.time() - t)
#结果是5.0047078132629395秒。这里,start()之后紧接着join(),意味着每一个线程都要在下一次循环之前运行到末尾,所以和不使用多线程没什么区别。但是,如果要计算多线程的运行时间,就需要使用这个join()
我们来看看没有加入的情况()
从线程导入线程
t=time.time()
for _ in范围(5):
th=线程(target=myfun)
th.start()
print(time.time() - t)
#结果是0.000980201721191406秒。它甚至没有等待1秒钟,所以它输出结果。而且,打印完这个才输出了5个2。这是因为print(time.time()-t)是与那五个循环不同的第六个线程,它不会等五个线程结束后才开始运行。所以不可能得到以上五个线程的运行时间。我们需要使用join()来等待所有五个线程完成运行。
代码如下所示
从线程导入线程
t=time.time()
ths=[]
for _ in范围(5):
th=线程(target=myfun)
th.start()
th .追加(th)
对于本中的第:
th.join()
print(time.time() - t)
#结果是1.0038363933563232。上面定义的ths列表存储了这些线程。最后,循环用于确保每个线程在计算时间差之前已经完成运行。
Join()不仅用于这种情况。当一步代码执行依赖于代码执行的完成时,应该添加join()命令。
现在我们已经了解了多线程的一般用法,我们可以在大多数情况下使用它。以下是一些细节。
其他(1)线程名称我们直接看下面的代码。
导入线程
print(threading.current_thread()。getName())
def myfun():
时间.睡眠(1)
print(threading.current_thread()。姓名)
a=1 1
对于范围(5)中的I:
th=线程。Thread(target=myfun,name=thread {} 。格式(一))
th.start()
#输出结果
主线程
线程0
线程1
线程4
线程3
线程2,解释
Threading.current_thread()表示当前线程。您可以调用name或getName()来获取线程名称。默认情况下,任何进程都会启动一个线程。默认名为MainThread,即主程序占用一个线程。这个线程独立于thread新添加的线程,主线程会继续运行,而不会等待其余线程运行完。之前没有join()就无法计算运行时间,因为主线程是先完成的。线程意味着运行这个函数来启动一个新的线程。给它添加一个name参数来指定这个函数的线程名,在这个函数中打印线程名会显示在循环中有两种类型打印name参数的对应值。第一次打印(threading.current _ thread()。name)是mainthread第二种类型的打印(th.name)是线程1和其他(2)线程函数。上面我们用了thread函数的target name参数,下面再说它的其他参数。
Args指定target对应的函数的参数,由tuple传入。例如,args=(3,)daemon main thread默认为False,如果没有指定,它将继承父线程的值。如果主线程的运行结束,该线程也将停止运行;不管主线程如何,线程都将继续运行,直到结束。(要看这个参数的效果,你应该在py文件中写代码,在cmd中运行,而不是在jupyter notebook中,因为这里会有更多的线程干扰。)group是保留参数,以后用来扩展ThreadGroup类。现在无用的(3)线程。Thread和thread对象上面的threading.current_thread()创建了一个thread对象,它有以下属性和方法
GetName()。name获取线程名setName()设置线程名start() join()。这两位前面说过join()有一个超时参数,意思是在等待这个线程结束的时候,如果等待时间超过了这个时间,就不再等待了。继续下面的代码,但是,这个线程不会被中断。run()也运行这个线程,但是在继续执行下面的代码之前,您必须等到这个线程完成运行。(如果把上面的start都改成run,就相当于不运行多线程了。)is_alive()如果这个线程还没有运行完,True或false,daemon返回线程的daemon set daemon(True),将线程的daemon (4)线程设置为一些直接调用的变量。
Threading.currentThread():返回当前线程变量threading.enumerate():返回包含正在运行的线程的列表threading.activeCount():返回正在运行的线程数,结果与len(threading.enumerate())相同。
涉及
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。