gpt4 book ai didi

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

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 33 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Python多线程编程之threading模块详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

1、介绍

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

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

2、Python如何创建线程

2.1 方法一:

创建Thread对象 。

步骤:

1.目标函数 。

2.实例化Thread对象 。

3.调用start()方法 。


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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类 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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、线程的用法

3.1 确定当前的线程

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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线程中资源共享,如果不对资源加上互斥锁,有可能导致数据不准确.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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)

互斥锁 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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)

互斥锁引发的另一个问题:死锁 。

死锁产生的原理:

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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)

如何避免产生死锁:

锁超时操作 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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模块内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。

原文链接:https://blog.csdn.net/qq_31385393/article/details/115873831 。

最后此篇关于Python多线程编程之threading模块详解的文章就讲到这里了,如果你想了解更多关于Python多线程编程之threading模块详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com