第一章 Python 线程的概念及使用方法

Python中的进程与线程

第一章 Python 线程的概念及使用方法



第一章 Python 线程的概念及使用方法

一、什么是线程

一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

二、线程的优势

  1. 能够在后台处理一些耗时长的程序;
  2. 方便处理需要等待监听的任务,如网络发送与接受数据、文件读取数据等。

三、Threading 中的Thread 模块创建线程

python中的多线程主要调用threading库中的Thread类来实现。

import threading
import time

def Hello(name):
    print('Hello,', name)
    time.sleep(2)	#等待2s
    print('Goodbye',name)
def Hi(name):
    print('Hi,', name)
    time.sleep(5)	#等待5s
    print('Goodbye',name)
'''
	Thread(target,args,kwargs)
		target-绑定线程函数
		args 元组 给线程函数位置传参,注意,格式必须是元组且在最后一个参数后面要跟上一个逗号
		kwargs 字典 给线程函数键值传参
'''
p1 = threading.Thread(target=Hello, args=('CSDN',))  # p1是Thread的一个实例化对象
p2 = threading.Thread(target=Hi, args=('GitHub',))  # p2是Thread的另一个实例化对象
# 执行上面两个子线程
p1.start()
p2.start()
time.sleep(1)	#等待1s
print("主线程的输出在此")

运行上面的程序可以发现,主线程的print()并没有等待p1和p2两个子线程运行完毕,主线程和p1,p2两个子线程是同时进行的,主进程在等待1s后就直接输出print()的内容。但在整个程序中,主进程要等待所有非守护子线程结束之后,主线程才会退出——Process finished with exit code 0。

那么如何实现在子线程结束以后再开始调用主线程的print呢?这里就用到了回收线程的概念。

四、回收线程

主要使用p1.join([timeout])语句,代码如下:

import threading
import time

def Hello(name):
    print('Hello,', name)
    time.sleep(2)	#等待2s
    print('Goodbye',name)
def Hi(name):
    print('Hi,', name)
    time.sleep(5)	#等待5s
    print('Goodbye',name)
'''
	Thread(target,args,kwargs)
		target-绑定线程函数
		args 元组 给线程函数位置传参,注意,格式必须是元组且在最后一个参数后面要跟上一个逗号
		kwargs 字典 给线程函数键值传参
'''
p1 = threading.Thread(target=Hello, args=('CSDN',))  # p1是Thread的一个实例化对象
p2 = threading.Thread(target=Hi, args=('GitHub',))  # p2是Thread的另一个实例化对象
# 执行上面两个子线程
p1.start()
p2.start()
#回收两个子线程
p1.join()
p2.join()
time.sleep(1)	#等待1s
print("主线程的输出在此")

可以看到,在加入join()语句以后,非守护线程结束以后才会进行后续主线程的相关操作。那么,什么是非守护线程呢?

五、守护线程与非守护线程

一般的子线程默认为非守护线程。但有时候我们的线程需要一直启动着,直到主线程退出以后,子线程也一并退出,这类子线程便是守护线程。当主线程结束以后,不管守护线程有没有运行完,都会跟随主线程一并退出,守护主线程。

import threading
import time

def Hello(name):
    print('Hello,', name)
    time.sleep(2)  #等待2s
    print('Goodbye',name)
def Hi(name):
    print('Hi,', name)
    time.sleep(5)  #等待3s
    print('Goodbye',name)
'''
   Thread(target,args,kwargs)
      target-绑定线程函数
      args 元组 给线程函数位置传参,注意,格式必须是元组且在最后一个参数后面要跟上一个逗号
      kwargs 字典 给线程函数键值传参
'''
p1 = threading.Thread(target=Hello, args=('CSDN',))  # p1是Thread的一个实例化对象
p2 = threading.Thread(target=Hi, args=('GitHub',))  # p2是Thread的另一个实例化对象
#设置p2子线程为守护线程
p2.setDaemon(True)
# 执行上面两个子线程
p1.start()
p2.start()

time.sleep(1)  #等待1s
print("主线程的输出在此")

结果可以看出来,p2为守护线程,主线程和p1、p2线程同时开始执行,当p1执行完以后,主线程结束退出,p2作为守护线程也同时退出,没有输出“Goodbye,GitHub”。

上述多线程方法实现的时间性能提速是因为CPU的并发执行,但在Python中这并不是并行执行,而是CPU在线程切换之间实现的(叫做通道技术),之所以不能像JAVA一样实现多线程并行,是因为受到了全局解释器锁(Global Interpreter Lock,GIL)的影响——不管有多少个CPU,在同一时间内,python解释器只能运行一个线程的代码。

因此,将使用多进程来实现并行。这将在下一章中提及。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每日力扣的疏白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值