• python_线程的开启、守护线程、锁、死锁、事件、定时器、条件、队列、池


    0、承上

       什么是线程?

        CPU调度的最小单位。

        线程是进程的必要组成单位。

      主线程:

        程序开始运行的时候,就产生了一个主线进程来运行这个程序。

      子线程:

        是由主线程开启的其他线程。

    ·  各线程之间的工作关系

        异步的

        数据共享的

      GIL锁:Cpython解释器中有一把锁,锁的是线程。

      线程是CPU调度的最小单位

      

    1、线程的开启

       线程不能在外界干扰下结束,而是等待程序执行完毕才结束的,主线程要等待子线程的结束而结束

     1 from threading import Thread, currentThread
     2 
     3 def t_func():
     4     global n
     5     n -= 1
     6     print(currentThread())
     7 
     8 if __name__ == '__main__':
     9     n = 100
    10     t_lst = []
    11     for i in range(100):
    12         t = Thread(target=t_func)
    13         t.start()
    14         t_lst.append(t)
    15         print(t.ident, t.name, t.is_alive())
    16     for t in t_lst:
    17         t.join()
    18     print(n)
    线程的开启
    D:Python36python.exe E:/Python/草稿纸0.py
    <Thread(Thread-1, started 20124)>
    20124 Thread-1 True
    <Thread(Thread-2, started 20128)>
    20128 Thread-2 True
    <Thread(Thread-3, started 20132)>
    20132 Thread-3 True
    <Thread(Thread-4, started 20136)>
    20136 Thread-4 True
    <Thread(Thread-5, started 20140)>
    20140 Thread-5 True
    <Thread(Thread-6, started 20144)>
    20144 Thread-6 True
    <Thread(Thread-7, started 20148)>
    20148 Thread-7 True
    <Thread(Thread-8, started 20152)>
    20152 Thread-8 True
    <Thread(Thread-9, started 20156)>
    20156 Thread-9 True
    <Thread(Thread-10, started 20160)>
    20160 Thread-10 True
    <Thread(Thread-11, started 20164)>
    20164 Thread-11 True
    <Thread(Thread-12, started 20168)>
    20168 Thread-12 True
    <Thread(Thread-13, started 20172)>
    20172 Thread-13 True
    <Thread(Thread-14, started 20176)>
    20176 Thread-14 True
    <Thread(Thread-15, started 20180)>
    20180 Thread-15 True
    <Thread(Thread-16, started 20184)>
    20184 Thread-16 True
    <Thread(Thread-17, started 20188)>
    20188 Thread-17 True
    <Thread(Thread-18, started 20192)>
    20192 Thread-18 True
    <Thread(Thread-19, started 20196)>
    20196 Thread-19 True
    <Thread(Thread-20, started 20200)>
    20200 Thread-20 True
    <Thread(Thread-21, started 20204)>
    20204 Thread-21 True
    <Thread(Thread-22, started 20208)>
    20208 Thread-22 True
    <Thread(Thread-23, started 20212)>
    20212 Thread-23 True
    <Thread(Thread-24, started 20216)>
    20216 Thread-24 True
    <Thread(Thread-25, started 20220)>
    20220 Thread-25 True
    <Thread(Thread-26, started 20224)>
    20224 Thread-26 True
    <Thread(Thread-27, started 20228)>
    20228 Thread-27 True
    <Thread(Thread-28, started 20232)>
    20232 Thread-28 True
    <Thread(Thread-29, started 20236)>
    20236 Thread-29 True
    <Thread(Thread-30, started 20240)>
    20240 Thread-30 True
    <Thread(Thread-31, started 20244)>
    20244 Thread-31 True
    <Thread(Thread-32, started 20248)>
    20248 Thread-32 True
    <Thread(Thread-33, started 20252)>
    20252 Thread-33 False
    <Thread(Thread-34, started 20256)>
    20256 Thread-34 True
    <Thread(Thread-35, started 20260)>
    20260 Thread-35 True
    <Thread(Thread-36, started 20264)>
    20264 Thread-36 False
    <Thread(Thread-37, started 20268)>
    20268 Thread-37 True
    <Thread(Thread-38, started 20272)>
    20272 Thread-38 True
    <Thread(Thread-39, started 20276)>
    20276 Thread-39 False
    <Thread(Thread-40, started 20280)>
    20280 Thread-40 True
    <Thread(Thread-41, started 20284)>
    20284 Thread-41 True
    <Thread(Thread-42, started 20288)>
    20288 Thread-42 True
    <Thread(Thread-43, started 20292)>
    20292 Thread-43 False
    <Thread(Thread-44, started 20296)>
    20296 Thread-44 True
    <Thread(Thread-45, started 20300)>
    20300 Thread-45 False
    <Thread(Thread-46, started 20304)>
    20304 Thread-46 True
    <Thread(Thread-47, started 20308)>
    20308 Thread-47 True
    <Thread(Thread-48, started 20312)>
    20312 Thread-48 True
    <Thread(Thread-49, started 20316)>
    20316 Thread-49 False
    <Thread(Thread-50, started 20320)>
    20320 Thread-50 False
    <Thread(Thread-51, started 20324)>
    20324 Thread-51 True
    <Thread(Thread-52, started 20328)>
    20328 Thread-52 True
    <Thread(Thread-53, started 20332)>
    20332 Thread-53 True
    <Thread(Thread-54, started 20336)>
    20336 Thread-54 True
    <Thread(Thread-55, started 20340)>
    20340 Thread-55 True
    <Thread(Thread-56, started 20344)>
    20344 Thread-56 True
    <Thread(Thread-57, started 20348)>
    20348 Thread-57 True
    <Thread(Thread-58, started 20352)>
    20352 Thread-58 True
    <Thread(Thread-59, started 20356)>
    20356 Thread-59 True
    <Thread(Thread-60, started 20360)>
    20360 Thread-60 True
    <Thread(Thread-61, started 20364)>
    20364 Thread-61 True
    <Thread(Thread-62, started 20368)>
    20368 Thread-62 False
    <Thread(Thread-63, started 20372)>
    20372 Thread-63 True
    <Thread(Thread-64, started 20376)>
    20376 Thread-64 True
    <Thread(Thread-65, started 20380)>
    20380 Thread-65 True
    <Thread(Thread-66, started 20384)>
    20384 Thread-66 True
    <Thread(Thread-67, started 20388)>
    20388 Thread-67 True
    <Thread(Thread-68, started 20392)>
    20392 Thread-68 False
    <Thread(Thread-69, started 20396)>
    20396 Thread-69 True
    <Thread(Thread-70, started 20400)>
    20400 Thread-70 True
    <Thread(Thread-71, started 20404)>
    20404 Thread-71 True
    <Thread(Thread-72, started 20408)>
    20408 Thread-72 False
    <Thread(Thread-73, started 20412)>
    20412 Thread-73 True
    <Thread(Thread-74, started 20416)>
    20416 Thread-74 True
    <Thread(Thread-75, started 20420)>
    20420 Thread-75 True
    <Thread(Thread-76, started 20424)>
    20424 Thread-76 True
    <Thread(Thread-77, started 20428)>
    20428 Thread-77 False
    <Thread(Thread-78, started 20432)>
    20432 Thread-78 True
    <Thread(Thread-79, started 20436)>
    20436 Thread-79 True
    <Thread(Thread-80, started 20440)>
    20440 Thread-80 True
    <Thread(Thread-81, started 20444)>
    20444 Thread-81 True
    <Thread(Thread-82, started 20448)>
    20448 Thread-82 True
    <Thread(Thread-83, started 20452)>
    20452 Thread-83 True
    <Thread(Thread-84, started 20456)>
    20456 Thread-84 True
    <Thread(Thread-85, started 20460)>
    20460 Thread-85 True
    <Thread(Thread-86, started 20464)>
    20464 Thread-86 False
    <Thread(Thread-87, started 20468)>
    20468 Thread-87 True
    <Thread(Thread-88, started 20472)>
    20472 Thread-88 True
    <Thread(Thread-89, started 20476)>
    20476 Thread-89 True
    <Thread(Thread-90, started 19584)>
    19584 Thread-90 True
    <Thread(Thread-91, started 19588)>
    19588 Thread-91 True
    <Thread(Thread-92, started 6800)>
    6800 Thread-92 True
    <Thread(Thread-93, started 19568)>
    19568 Thread-93 True
    <Thread(Thread-94, started 18904)>
    18904 Thread-94 True
    <Thread(Thread-95, started 19604)>
    19604 Thread-95 True
    <Thread(Thread-96, started 19608)>
    19608 Thread-96 True
    <Thread(Thread-97, started 19612)>
    19612 Thread-97 True
    <Thread(Thread-98, started 19620)>
    19620 Thread-98 True
    <Thread(Thread-99, started 19616)>
    19616 Thread-99 True
    <Thread(Thread-100, started 19624)>
    19624 Thread-100 True
    0
    
    Process finished with exit code 0
    结果

      

    2、守护线程

       主进程守护  会等待主进程的代码执行结束而结束。

    import time
    from multiprocessing import Process
    
    def func1():
        time.sleep(3)
        print('in func1')
    
    def func2():
        while True:
            time.sleep(0.5)
            print('in func2')
    if __name__ == '__main__':
        Process(target=func1).start()
        t = Process(target=func2)
        t.daemon = True
        t.start()
        print('主进程')
    进程守护
    D:Python36python.exe E:/Python/草稿纸0.py
    主进程
    in func1
    
    Process finished with exit code 0
    结果

      

       主线程守护  会等待主线程执行完毕才结束,主线程会等待所有子进程结束而结束。

     1 import time
     2 from threading import Thread
     3 
     4 def func1():
     5     time.sleep(3)
     6     print('in func1')
     7 
     8 def func2():
     9     while True:
    10         time.sleep(0.5)
    11         print('in func2')
    12 
    13 if __name__ == '__main__':
    14     Thread(target=func1).start()
    15     t = Thread(target=func2)
    16     t.setDaemon(True)
    17     t.start()
    18     print('主线程')
    守护线程
    D:Python36python.exe E:/Python/草稿纸0.py
    主线程
    in func2
    in func2
    in func2
    in func2
    in func2
    in func2
    in func1
    
    Process finished with exit code 0
    结果

      

    3、锁

     1 from threading import Thread
     2 
     3 def t_func():
     4     global n
     5     n -= 1
     6 
     7 if __name__ == '__main__':
     8     n = 200000
     9     t_lst = []
    10     for i in range(200000):
    11         t = Thread(target=t_func)
    12         t.start()
    13         t_lst.append(t)
    14     for t in t_lst:
    15         t.join()
    16     print(n)
    锁1
    D:Python36python.exe E:/Python/草稿纸0.py
    0
    
    Process finished with exit code 0
    结果
     1 import threading
     2 
     3 balance = 0
     4 def change_it(n):
     5     global balance
     6     balance = balance + n
     7     balance = balance - n
     8 
     9 def run_thread(n, lock):
    10     for i in range(150000):
    11         change_it(n)
    12 
    13 lock = threading.Lock()
    14 t1 = threading.Thread(target=run_thread, args=(5, lock))
    15 t2 = threading.Thread(target=run_thread, args=(5, lock))
    16 t1.start()
    17 t2.start()
    18 t1.join()
    19 t2.join()
    20 print(balance)
    线程之间的数据不安全
    D:Python36python.exe E:/Python/草稿纸0.py
    -5
    
    Process finished with exit code 0
    结果(异常)
    D:Python36python.exe E:/Python/草稿纸0.py
    0
    
    Process finished with exit code 0
    结果(正常)
     1 import threading
     2 
     3 balance = 0
     4 def change_it(n):
     5     global balance
     6     balance = balance + n
     7     balance = balance - n
     8 
     9 def run_thread(n, lock):
    10     for i in range(150000):
    11         with lock:
    12             change_it(n)
    13 
    14 lock = threading.Lock()
    15 t1 = threading.Thread(target=run_thread, args=(5, lock))
    16 t2 = threading.Thread(target=run_thread, args=(5, lock))
    17 t1.start()
    18 t2.start()
    19 t1.join()
    20 t2.join()
    21 print(balance)
    线程加锁
    D:Python36python.exe E:/Python/草稿纸0.py
    0
    
    Process finished with exit code 0
    结果

    4、死锁

      互斥锁和递归锁的区别:

        互斥锁在同一个线程中连续acquire一次以上就会死锁

        递归锁在同一个线程中可以连续的acquire多次而不会发生死锁

      普遍:递归锁可以替代互斥锁来解决死锁现象

      实际上:  递归锁的解决死锁实际上是牺牲了时间和空间的

        死锁本质上来讲是一种逻辑上的错误

        递归锁没有从本质上解决死锁的问题

       互斥锁

    1 from threading import Lock
    2 lock = Lock()
    3 lock.acquire()
    4 print(123)
    5 lock.release()
    互斥锁
    D:Python36python.exe E:/Python/草稿纸0.py
    123
    
    Process finished with exit code 0
    结果

      递归锁

    1 from threading import RLock
    2 
    3 lock = RLock()
    4 lock.acquire()
    5 lock.acquire()
    6 print(123)
    7 lock.release()
    递归锁
    D:Python36python.exe E:/Python/草稿纸0.py
    123
    
    Process finished with exit code 0
    结果

      吃面问题(死锁)

     1 from threading import Thread, Lock
     2 
     3 def eat1(name, fork_lock, noodle_lock):
     4     fork_lock.acquire()
     5     print(f'{name}拿到叉子了')
     6     noodle_lock.acquire()
     7     print(f'{name}拿到面条了')
     8     print(f'{name}吃面')
     9     noodle_lock.release()
    10     fork_lock.release()
    11 
    12 def eat2(name, fork_lock, noodke_lock):
    13     noodke_lock.acquire()
    14     print(f'{name}拿到面条了')
    15     fork_lock.acquire()
    16     print(f'{name}拿到叉子了')
    17     print(f'{name}吃面')
    18     fork_lock.release()
    19     noodke_lock.release()
    20 
    21 fork_lock = Lock()
    22 noodle_lock = Lock()
    23 Thread(target=eat1, args=('alex', fork_lock, noodle_lock)).start()
    24 Thread(target=eat2, args=('wusir', fork_lock, noodle_lock)).start()
    25 Thread(target=eat1, args=('yuan', fork_lock, noodle_lock)).start()
    26 Thread(target=eat2, args=('jin', fork_lock, noodle_lock)).start()
    吃面问题
    D:Python36python.exe E:/Python/草稿纸0.py
    alex拿到叉子了
    alex拿到面条了
    alex吃面
    wusir拿到面条了
    wusir拿到叉子了
    wusir吃面
    yuan拿到叉子了
    yuan拿到面条了
    yuan吃面
    jin拿到面条了
    jin拿到叉子了
    jin吃面
    
    Process finished with exit code 0
    结果

      递归锁解决死锁现象

     1 from threading import Thread, RLock
     2 
     3 def eat1(name, fork_lock, noodle_lock):
     4     fork_lock.acquire()
     5     print(f'{name}拿到叉子了')
     6     noodle_lock.acquire()
     7     print(f'{name}拿到面了')
     8     print(f'{name}吃面')
     9     noodle_lock.release()
    10     fork_lock.release()
    11 
    12 def eat2(name, fork_lock, noodle_lock):
    13     noodle_lock.acquire()
    14     print(f'{name}拿到面条了')
    15     fork_lock.acquire()
    16     print(f'{name}拿到叉子了')
    17     print(f'{name}吃面')
    18     fork_lock.release()
    19     noodle_lock.release()
    20 
    21 noodle_lock = fork_lock = RLock()
    22 Thread(target=eat1, args=('alex', fork_lock, noodle_lock)).start()
    23 Thread(target=eat2, args=('wusir', fork_lock, noodle_lock)).start()
    24 Thread(target=eat1, args=('yuan', fork_lock, noodle_lock)).start()
    25 Thread(target=eat2, args=('jin', fork_lock, noodle_lock)).start()
    递归锁
    D:Python36python.exe E:/Python/草稿纸0.py
    alex拿到叉子了
    alex拿到面了
    alex吃面
    wusir拿到面条了
    wusir拿到叉子了
    wusir吃面
    yuan拿到叉子了
    yuan拿到面了
    yuan吃面
    jin拿到面条了
    jin拿到叉子了
    jin吃面
    
    Process finished with exit code 0
    结果
     1 import time
     2 from threading import Thread, Lock
     3 
     4 def eat1(name, lock):
     5     lock.acquire()
     6     print(f'{name}拿到叉子了')
     7     print(f'{name}拿到面条了')
     8     print(f'{name}吃面')
     9     lock.release()
    10 
    11 def eat2(name, lock):
    12     lock.acquire()
    13     print(f'{name}拿到面条了')
    14     time.sleep(1)
    15     print(f'{name}拿到叉子了')
    16     print(f'{name}吃面')
    17     lock.release()
    18 
    19 noodle_fork_lock = Lock()
    20 Thread(target=eat1, args=('alex', noodle_fork_lock)).start()
    21 Thread(target=eat2, args=('wusir', noodle_fork_lock)).start()
    22 Thread(target=eat1, args=('yuan', noodle_fork_lock)).start()
    23 Thread(target=eat2, args=('jin', noodle_fork_lock)).start()
    简化
    D:Python36python.exe E:/Python/草稿纸0.py
    alex拿到叉子了
    alex拿到面条了
    alex吃面
    wusir拿到面条了
    wusir拿到叉子了
    wusir吃面
    yuan拿到叉子了
    yuan拿到面条了
    yuan吃面
    jin拿到面条了
    jin拿到叉子了
    jin吃面
    
    Process finished with exit code 0
    结果

    5、事件

     未完待续。。。 

    6、定时器

      未完待续。。。 

      

    7、条件

      未完待续。。。 

      

    8、队列

      未完待续。。。 

      

    9、池

      未完待续。。。 

  • 相关阅读:
    mybatis(十)缓存
    mybatis(八)复杂查询
    mybatis(六)分页
    mybatis(九)动态SQL
    mybatis(七)只用注解开发
    mybatis(五) 日志
    log4j.properties 相关配置
    mybatis(四)中可能出现的问题
    MyBatis(三) 配置解析
    IIS 发布 .net core 3.1
  • 原文地址:https://www.cnblogs.com/ZN-225/p/9199019.html
Copyright © 2020-2023  润新知