Python如何创建线程,线程的用法包括哪些
Admin 2022-06-30 群英技术资讯 780 次浏览
这篇文章主要讲解了“Python如何创建线程,线程的用法包括哪些”,文中的讲解内容简单、清晰、详细,对大家学习或是工作可能会有一定的帮助,希望大家阅读完这篇文章能有所收获。下面就请大家跟着小编的思路一起来学习一下吧。线程是什么?线程有啥用?线程和进程的区别是什么?
线程是操作系统能够进行运算调度的最小单位。被包含在进程中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
创建Thread对象
步骤:
1.目标函数
2.实例化Thread对象
3.调用start()方法
import threading
# 目标函数1
def fun1(num):
for i in range(num):
print('线程1: 第%d次循环:' % i)
# 目标函数2
def fun2(lst):
for ele in lst:
print('线程2: lst列表中元素 %d' % ele)
def main():
num = 10
# 实例化Thread对象
# target参数一定为一个函数,且不带括号
# args参数为元组类型,参数为一个时一定要加逗号
t1 = threading.Thread(target=fun1, args=(num,))
t2 = threading.Thread(target=fun2, args=([1, 2, 3, 4, 5],))
# 调用start方法
t1.start()
t2.start()
if __name__ == '__main__':
main()
创建子类继承threading.Thread类
import threading
import os
class Person(threading.Thread):
def run(self):
self.sing(5)
self.cook()
@staticmethod
def sing(num):
for i in range(num):
print('线程[%d]: The person sing %d song.' % (os.getpid(), i))
@staticmethod
def cook():
print('线程[%d]:The person has cooked breakfast.' % os.getpid())
def main():
p1 = Person()
p1.start()
p2 = Person()
p2.start()
if __name__ == '__main__':
main()
import threading
import time
import logging
def fun1():
print(threading.current_thread().getName(), 'starting')
time.sleep(0.2)
print(threading.current_thread().getName(), 'exiting')
def fun2():
# print(threading.current_thread().getName(), 'starting')
# time.sleep(0.3)
# print(threading.current_thread().getName(), 'exiting')
logging.debug('starting')
time.sleep(0.3)
logging.debug('exiting')
logging.basicConfig(
level=logging.DEBUG,
format='[%(levelname)s] (%(threadName)-10s) %(message)s'
)
def main():
t1 = threading.Thread(name='线程1', target=fun1)
t2 = threading.Thread(name='线程2', target=fun2)
t1.start()
t2.start()
if __name__ == '__main__':
main()
区别
守护线程如何搞
import threading
import time
import logging
def daemon():
logging.debug('starting')
# 添加延时,此时主线程已经退出,exiting不会打印
time.sleep(0.2)
logging.debug('exiting')
def non_daemon():
logging.debug('starting')
logging.debug('exiting')
logging.basicConfig(
level=logging.DEBUG,
format='[%(levelname)s] (%(threadName)-10s) %(message)s'
)
def main():
# t1 = threading.Thread(name='线程1', target=daemon)
# t1.setDaemon(True)
t1 = threading.Thread(name='线程1', target=daemon, daemon=True)
t2 = threading.Thread(name='线程2', target=non_daemon)
t1.start()
t2.start()
# 等待守护线程完成工作需要调用join()方法,默认情况join会无限阻塞,可以传入浮点值,表示超时时间
t1.join(0.2)
t2.join(0.1)
if __name__ == '__main__':
main()
目的:
Python线程中资源共享,如果不对资源加上互斥锁,有可能导致数据不准确。
import threading
import time
g_num = 0
def fun1(num):
global g_num
for i in range(num):
g_num += 1
print('线程1 g_num = %d' % g_num)
def fun2(num):
global g_num
for i in range(num):
g_num += 1
print('线程2 g_num = %d' % g_num)
def main():
t1 = threading.Thread(target=fun1, args=(1000000,))
t2 = threading.Thread(target=fun1, args=(1000000,))
t1.start()
t2.start()
if __name__ == '__main__':
main()
time.sleep(1)
print('主线程 g_num = %d' % g_num)
互斥锁
import threading
import time
g_num = 0
L = threading.Lock()
def fun1(num):
global g_num
L.acquire()
for i in range(num):
g_num += 1
L.release()
print('线程1 g_num = %d' % g_num)
def fun2(num):
global g_num
L.acquire()
for i in range(num):
g_num += 1
L.release()
print('线程2 g_num = %d' % g_num)
def main():
t1 = threading.Thread(target=fun1, args=(1000000,))
t2 = threading.Thread(target=fun1, args=(1000000,))
t1.start()
t2.start()
if __name__ == '__main__':
main()
time.sleep(1)
print('主线程 g_num = %d' % g_num)
互斥锁引发的另一个问题:死锁
死锁产生的原理:

import threading
import time
g_num = 0
L1 = threading.Lock()
L2 = threading.Lock()
def fun1():
L1.acquire(timeout=5)
time.sleep(1)
L2.acquire()
print('产生死锁,并不会打印信息')
L2.release()
L1.release()
def fun2():
L2.acquire(timeout=5)
time.sleep(1)
L1.acquire()
print('产生死锁,并不会打印信息')
L1.release()
L2.release()
def main():
t1 = threading.Thread(target=fun1)
t2 = threading.Thread(target=fun2)
t1.start()
t2.start()
if __name__ == '__main__':
main()
time.sleep(1)
print('主线程 g_num = %d' % g_num)
如何避免产生死锁:
锁超时操作
import threading
import time
g_num = 0
L1 = threading.Lock()
L2 = threading.Lock()
def fun1():
L1.acquire()
time.sleep(1)
L2.acquire(timeout=5)
print('超时异常打印信息1')
L2.release()
L1.release()
def fun2():
L2.acquire()
time.sleep(1)
L1.acquire(timeout=5)
print('超时异常打印信息2')
L1.release()
L2.release()
def main():
t1 = threading.Thread(target=fun1)
t2 = threading.Thread(target=fun2)
t1.start()
t2.start()
if __name__ == '__main__':
main()
time.sleep(1)
print('主线程 g_num = %d' % g_num)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要给大家分享saga分布式事务的内容,下文分享了saga的理论知识和用python实现saga分布式事务的实例,对大家理解saga分布式事务有一定的帮助,感兴趣的朋友可以参考一下,希望大家阅读完这篇文章能有所收获,下面我们一起来学习一下吧。
这篇文章主要介绍了python 教程之blinker 信号库,文章基于python的相关资料展开详细的内容说明。具有一定的参考价价值,需要的小伙伴可以参考一下
property是一个类,可以把一个方法当做属性进行使用,这样做可以简化代码使用。实际上就是装饰类中属性的gettersetter方法,使得属性可以通过对象.属性的方式获取或设置 使用property的两种方式装饰器方式类属性方式2.装饰器方式@property修饰获取的方法getter,方法名必须和属性名一样@age.setter修饰设置值的方法sett
这篇文章主要介绍了Python中的min及返回最小值索引的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
内容介绍1.引言2.工作原理3.使用Colorama库4.改变输出文本颜色5.改变输出文本背景6.改变输出文本亮度7.总结1.引言创建命令行程序很棒:命令行可以按照我们的设定完成相应的工作,相比GU
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008