zoukankan      html  css  js  c++  java
  • Python中的多线程

    1、什么是线程

      进程其实不是一个执行单位,进程是一个资源单位

      每个进程内自带一个线程,线程才是CPU上的执行单位

      

    如果把操作系统比喻为一座工厂

      在工厂内每造出一个车间===》启动一个进程

      每个车间内至少有一条流水线===》每个进程内至少有一个线程

    线程==》单指代码的执行过程

    进程==》资源的申请与销毁的过程

    2、进程VS线程

      1)内存共享or隔离

        多个进程内存空间彼此隔离

        同一进程下的多个线程共享该进程内的数据

      2)创建速度

        造线程的速度要远远快于造进程

    一、开启线程的两种方式(重点)

    
    
    方式一:导入Thread模块

    1
    from threading import Thread 2 import time 3 5 def task(name): 6 print('%s is running' %name) 7 time.sleep(3) 8 print('%s is done' %name) 9 if __name__ == '__main__': 10 t=Thread(target=task,args=('子线程',)) 11 t.start() 12 print('')
    
    
    方式二:创建类继承Thread

    1
    from threading import Thread 2 import time 3 4 6 # class Mythread(Thread): 7 # def run(self): 8 # print('%s is running' %self.name) 9 # time.sleep(3) 10 # print('%s is done' %self.name) 11 # 12 # if __name__ == '__main__': 13 # t=Mythread() 14 # t.start() 15 # print('主')

    二、线程VS进程(重点)

     1 # from threading import Thread
     2 # from multiprocessing import Process
     3 # import time
     4 #
     5 # def task(name):
     6 #     print('%s is running' %name)
     7 #     time.sleep(3)
     8 #     print('%s is done' %name)
     9 #
    10 # if __name__ == '__main__':
    11 #     t=Thread(target=task,args=('子线程',))
    12 #     # t=Process(target=task,args=('子进程',))
    13 #     t.start()
    14 #     print('主')

    线程运行结果:

    进程运行结果:

     2)同一进程下的多个线程共享该进程内的数据(了解知识点)

     1 # from threading import Thread
     2 # import time
     3 #
     4 # x=100
     5 # def task():
     6 #     global x
     7 #     x=0
     8 #
     9 # if __name__ == '__main__':
    10 #     t=Thread(target=task,)
    11 #     t.start()
    12 #     # time.sleep(3)
    13 #     t.join()
    14 #     print('主',x)
    View Code

    3)查看pid(了解知识点)

    注意:一个进程中的子线程pid相同

     1 from threading import Thread
     2 import time,os
     3 
     4 def task():
     5     print(os.getpid())
     6 
     7 if __name__ == '__main__':
     8     t=Thread(target=task,)
     9     t.start()
    10     print('',os.getpid())
    View Code

     三、线程对象的其他方法和属性(熟悉知识点)

    1)主进程等子进程是因为主进程要给子进程收尸

    2)进程必须等待其内部所有线程都运行完毕才结束

     1 # from threading import Thread
     2 # import time
     3 #
     4 # def task(name):
     5 #     print('%s is running' %name)
     6 #     time.sleep(3)
     7 #     print('%s is done' %name)
     8 # if __name__ == '__main__':
     9 #     t=Thread(target=task,args=('子线程',))
    10 #     t.start()
    11 #     print('主')
    12 #
    View Code
     1 from threading import Thread,current_thread,active_count,enumerate
     2 import time
     3 
     4 
     5 def task():
     6     print('%s is running' % current_thread().name)
     7     time.sleep(3)
     8     print('%s is done' % current_thread().name)
     9 
    10 
    11 if __name__ == '__main__':
    12     t = Thread(target=task,name='xxx')
    13     t.start()
    14     # t.join()
    15     # print(t.is_alive())
    16     # print(t.getName())
    17     # print(t.name)
    18     # print('主',active_count())
    19     # print(enumerate())
    20 
    21     # t.join()
    22     current_thread().setName('主线程')
    23     print('',current_thread().name)
    View Code

    四、守护线程(熟悉知识点)

    守护线程(daemon)会在本进程内所有非守护的线程都死掉了才跟着死

    即:

      守护线程其实守护的是整个进程的运行周期(进程内所有的非守护线程都运行完毕)

     1 # from threading import Thread,current_thread
     2 # import time
     3 #
     4 #
     5 # def task():
     6 #     print('%s is running' % current_thread().name)
     7 #     time.sleep(3)
     8 #     print('%s is done' % current_thread().name)
     9 #
    10 #
    11 # if __name__ == '__main__':
    12 #     t = Thread(target=task,name='守护线程')
    13 #     t.daemon=True
    14 #     t.start()
    15 #     print('主')
    守护进程
     1 from threading import Thread
     2 import time
     3 def foo():
     4     print(123)
     5     time.sleep(3)
     6     print("end123")
     7 
     8 def bar():
     9     print(456)
    10     time.sleep(1)
    11     print("end456")
    12 
    13 
    14 t1=Thread(target=foo)
    15 t2=Thread(target=bar)
    16 
    17 t1.daemon=True
    18 t1.start()
    19 t2.start()
    20 print("main-------")
    21 
    22 '''
    23 123
    24 456
    25 main-------
    26 end456
    27 
    28 '''
    较迷惑人的守护进程

    五、互斥锁(熟悉知识点)

     1 from threading import Thread,Lock
     2 import time
     3 
     4 mutex=Lock()
     5 
     6 x=100
     7 def task():
     8     global x
     9     # mutex.acquire()
    10     temp=x
    11     time.sleep(0.1)
    12     x=temp-1
    13     # mutex.release()
    14 
    15 if __name__ == '__main__':
    16     t_l=[]
    17     start=time.time()
    18     for i in range(100):
    19         t=Thread(target=task)
    20         t_l.append(t)
    21         t.start()
    22 
    23     for t in t_l:
    24         t.join()
    25 
    26     stop=time.time()
    27     print(x,stop-start)
    互斥锁

    六、死锁现象与递归锁(熟悉知识点)

      如果用Lock(互斥锁),会发生死锁现象

      递归锁本质是一把锁,可连续acqruie,但只有其上的计数为0时其他线程才可对其调用

     1 from threading import Thread,Lock,active_count,RLock
     2 import time
     3 
     4 # mutexA=Lock()
     5 # mutexB=Lock()
     6 obj=RLock() #递归锁的特点:可以连续的acquire
     7 mutexA=obj
     8 mutexB=obj
     9 
    10 class Mythread(Thread):
    11     def run(self):
    12         self.f1()
    13         self.f2()
    14 
    15     def f1(self):
    16         mutexA.acquire()
    17         print('%s 拿到A锁' %self.name)
    18 
    19         mutexB.acquire()
    20         print('%s 拿到B锁' %self.name)
    21         mutexB.release()
    22 
    23         mutexA.release()
    24 
    25     def f2(self):
    26         mutexB.acquire()
    27         print('%s 拿到B锁' %self.name)
    28         time.sleep(1)
    29 
    30         mutexA.acquire()
    31         print('%s 拿到A锁' %self.name)
    32         mutexA.release()
    33 
    34         mutexB.release()
    35 
    36 if __name__ == '__main__':
    37     for i in range(10):
    38         t=Mythread()
    39         t.start()
    40     # print(active_count())
    View Code

    七、信号量(熟悉知识点)

      信号量本质上还是锁,但区别信号量是控制同一时刻并发执行的任务数

     1 from threading import Thread,Semaphore,current_thread
     2 import time,random
     3 
     4 sm=Semaphore(5)
     5 
     6 def task():
     7     with sm:
     8         print('%s 正在上厕所' %current_thread().name)
     9         time.sleep(random.randint(1,4))
    10 
    11 
    12 if __name__ == '__main__':
    13     for i in range(20):
    14         t=Thread(target=task)
    15         t.start()
    信号量
  • 相关阅读:
    mac上python3安装HTMLTestRunner
    双目深度估计传统算法流程及OpenCV的编译注意事项
    深度学习梯度反向传播出现Nan值的原因归类
    1394. Find Lucky Integer in an Array
    1399. Count Largest Group
    1200. Minimum Absolute Difference
    999. Available Captures for Rook
    509. Fibonacci Number
    1160. Find Words That Can Be Formed by Characters
    1122. Relative Sort Array
  • 原文地址:https://www.cnblogs.com/huyingsakai/p/9305912.html
Copyright © 2011-2022 走看看