栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python并行编程(一):线程的基本概念和线程的两种定义方法以及join()、setDaemon(True)的使用

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python并行编程(一):线程的基本概念和线程的两种定义方法以及join()、setDaemon(True)的使用

前言:本系列将包含Python并行编程的相关技术内容,包括Python线程、Python进程、并发编程的异步模式及终极大法Python分布式计算如Celery、SCOOP等相关技术。
关键词: threading multiprocessing asyncio Celery
线程的基本概念和线程的两种定义方法 线程是什么?

线程看起来就像轻量级的进程,而进程又是什么呢? 进程即我们平时运行程序,比如通过点击图标打开的浏览器,QQ都是进程,进程拥有自己的独立的内存空间地址,可以拥有多个线程;即线程是存在进程内,也就意味着一个进程内的线程可以共享一些资源,其线程间的切换也就比进程低得多,多个线程可以并行及并发执行,共享数据和资源,所以我们多数时候的线程通信都是利用共享信息的空间进行通信,这也是后面谈到的线程管理必备的多种线程通信方式了。

在Python怎么定义线程? 使用线程最简单的方式就是通过目标函数的实例化:
import threading
import time


# 用于实例化线程目标函数
def function(i):
    time.sleep(2)
    print('Thread {} is running.'.format(i))
    time.sleep(2)
    return


for i in range(5):
    # Python模块threading.Thread方法
    t = threading.Thread(target=function, args=(i, ))
    t.start()

运行截图如下:

通过以上程序我们看出,定义好我们需要运行的目标函数来实例化线程,然后传入参数target即函数名,然后如果需要运行的目标函数有参数需要传递的话即可传入args元组,注意此处传入的是元组tuple。
然后我们在调用start()方法后启动实例化的线程

使用线程模块实现新的线程:
import threading
import time


class myThread(threading.Thread):
    def __init__(self, i):
 threading.Thread.__init__(self)
 self.i = i

    def run(self):
 time.sleep(2)
 print('Thread {} is running.'.format(self.i))
 time.sleep(2)
 return


for i in range(1, 6):
    t = myThread(i)
    t.start()

运行截图如下:

通过上面的程序我们可以看出,我们需要定义新的Thread类的子类,并且通过重写__init__方法来传递参数,然后重写run()方法来实现目标函数,那么当我们创建出新的子类后就可以实例化该子类并通过start()方法来启动线程。

守护线程 setDaemon(True)

接下来我们在运行一段代码:

import threading
import time


class myThread(threading.Thread):
    def __init__(self, i):
 threading.Thread.__init__(self)
 self.i = i

    def run(self):
 time.sleep(2)
 print('Thread {} is running.'.format(self.i))
 time.sleep(2)
 return

print('Mian THread starting')

for i in range(1, 6):
    t = myThread(i)
    t.start()
    
print('Mian THread end')

运行截图如下:

当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时,主线程会创建多个子线程;我们在主线程添加了两句print()用于打印主线程的运行状态,我们可以看见在默认情况下主现成直接执行完就退出了,此时子线程们还在执行过程中,那么如果我们添加setDaemon(True)方法呢:

import threading
import time


class myThread(threading.Thread):
    def __init__(self, i):
 threading.Thread.__init__(self)
 self.i = i

    def run(self):
 time.sleep(2)
 print('Thread {} is running.'.format(self.i))
 time.sleep(2)
 return

print('Mian THread starting')

for i in range(1, 6):
    t = myThread(i)
    t.setDaemon(True)
    t.start()
    
print('Mian THread end')

运行截图如下:

我们可以在运行截图中看到,当我们使用setDaemon(True)方法,设置子线程为守护线程时,主线程一旦执行结束,则全部线程全部被终止执行,可能出现的情况就是,子线程的任务还没有完全执行结束,就被迫停止。
那么我们能不能让主线程等等我们的子线程,等待子线程运行结束后,主线程再终止呢,即实现守护线程相反的效果,答案是可以得。

阻塞线程 join()
import threading
import time


class myThread(threading.Thread):
    def __init__(self, i):
 threading.Thread.__init__(self)
 self.i = i

    def run(self):
 time.sleep(2)
 print('Thread {} is running.'.format(self.i))
 time.sleep(2)
 return


print('Mian THread starting')

threads = []
for i in range(1, 6):
    t = myThread(i)
    t.start()
    threads.append(t)

for t in threads:
    t.join()
    
print('Mian THread end')

运行截图如下:

我们可以看见主线程是在等待子线程运行结束才终止运行的,即join()所完成的工作就是线程同步,即主线程任务结束之后,进入阻塞状态,一直等待其他的子线程执行结束之后,主线程再终止。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号