• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Python多线程编程之threading模块详解

python 搞代码 4年前 (2022-01-07) 41次浏览 已收录 0个评论
文章目录[隐藏]

这篇文章主要介绍了Py来源gao.dai.ma.com搞@代*码网thon多线程编程之threading模块详解,文中有非常详细的代码示例,对正在学习python的小伙伴们有非常好的帮助,需要的朋友可以参考下

一、介绍

线程是什么?线程有啥用?线程和进程的区别是什么?

线程是操作系统能够进行运算调度的最小单位。被包含在进程中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

二、Python如何创建线程

2.1 方法一:

创建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() 

2.2 方法二:

创建子类继承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() 

三、线程的用法

3.1 确定当前的线程

 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() 

3.2 守护线程

区别

  •  普通线程:主线程等待子线程关闭后关闭
  • 守护线程:管你子线程关没关,主线程到时间就关闭

守护线程如何搞

  • 方法1:构造线程时传入dameon=True
  • 方法2:调用setDaemon()方法并提供参数True
 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() 

3.3 控制资源访问

目的:

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) 

到此这篇关于Python多线程编程之threading模块详解的文章就介绍到这了,更多相关python threading模块内容请搜索gaodaima搞代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持gaodaima搞代码网

以上就是Python多线程编程之threading模块详解的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Python多线程编程之threading模块详解

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址