python的多线程及线程间的通信方式

1. 概述

线程是操纵系统能够进行运算调度的最小单位。一条线程是指进程中一个单一顺序的控制流。线程可以为内核线程和用户线程。而一个进程中有可以同时拥有多个线程执行,这种情况就被称为多线程。
并发与并行: 线程的并发是指处理器CPU在极短的时间内交替执行每个线程,而并行是指CPU同时处理多个线程。

2. 创建线程的方法

在python中,创建线程有两个方法,一个是通过继承Thread类并重写Thread类的run方法来创建线程,另一个就是通过创建Thread类对象并指定要执行的函数来实现的。

>通过继承Thread类来实现
from threading import Thread
from threading import currentThread
# 创建一个类继承Thread类
class T1(Thread):
	# 重写run方法
	def run(self):
		# 打印信息
		print(currentThread().name+"工作了!")

if __name__=="__main__":
	# 创建线程1和线程2,其中T1类由于没有自定义初始化方法,所以会自动调用其父类Thread的初始化方法。
	t1 = T1(name="线程1")
	t2 = T1(name="线程2")
	# 启动线程
	t1.start()
	t2.start()
	# 让主线程在这行代码后等t1和t2线程运行完后再执行后续代码
	t1.join()
	t2.join()
	# 打印结束语句
	print("t1和t2线程执行完毕")

>通过创建Thread类对象指定要执行的函数实现
from threading import Thread
from threading import currentThread

# 定义线程需要执行的函数
def t1(m:int):
    # 打印当前线程名信息
    print(currentThread().name+"工作了!"+str(m))

if __name__=="__main__":
    # 创建线程t1和t2,通过Thread类
    th1 = Thread(target=t1,args=(1,),name="线程1")
    th2 = Thread(target=t1, args=(2,), name="线程2")
    # 启动线程
    th1.start()
    th2.start()
    th1.join()
    th2.join()
    # 上面join方法的目的就是让下面这句话在th1和th2线程执行完后再执行下面这句话
    print("线程1和线程2任务执行完了")
3. 线程间的通信机制
>共享变量

通过共享变量来实现,简单来说就是定义一个全局变量来实现,具体示例如下:

from threading import Thread
from threading import currentThread

def task():
    global var
    while var:
        print(currentThread().name + "打印了" + str(var.pop()))

if __name__ == "__main__":
    var = [1, 2, 3, 4, 5, 6, 7]
    t1 = Thread(target=task, name="线程1")
    t2 = Thread(target=task, name="线程2")
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print("执行结束!")

在上述线程中,t1和t2两个线程共享了变量var,不过使用这种方式时,需要注意线程之间的同步问题(具体参见《生产者消费者模式的实现》)
上述程序的执行结果如下:
在这里插入图片描述

>使用Queue实现
from queue import Queue
from threading import Thread
from threading import currentThread

# 定义一个方法,不断向队列中输入数据
def task_put(var):
    for i in range(1, 8):
        print(currentThread().name+"向队列中输入了"+str(i))
        var.put(i)

# 定义一个方法,不断从队列中取出数据
def task(var):
    while not var.empty():
        print(currentThread().name + "输出了" + str(var.get()))
        # 该方法主要是和后面的var.join()语句联用,在使用Queue时,每次get数据并处理后,都要调用一次task_done()方法,来告知var.join()方法是否需要阻塞(即是执行主线程后续代码或退出主线程还是继续让主线程等待),并且在Queue为空时,程序执行主线程后续代码或退出主线程。
        var.task_done()


if __name__ == "__main__":
    var = Queue(7)
    t1 = Thread(target=task_put, args=(var,),name="线程1")
    t2 = Thread(target=task, args=(var,),name="线程2")
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    var.join()
    print("执行完毕")

在本方法中,由于Queue本身就是线程安全的,所以不需要考虑线程之间的同步问题。上述程序的执行结果如下:
在这里插入图片描述

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值