zoukankan      html  css  js  c++  java
  • python-day33(线程)

    一. 线程(threading模块)

      线程是CPU的最小执行单位,进程: 资源单位

      multiprocess模块完全模仿了threading模块的接口,二者在使用层面,有很大的相似性

     1 import time
     2 from threading import Thread
     3 #多线程并发,是不是看着和多进程很类似
     4 def func(n):
     5     time.sleep(1)
     6     print(n)
     7 
     8 #并发效果,1秒打印出了所有的数字
     9 for i in range(10):
    10     t = Thread(target=func,args=(i,))
    11     t.start()
    多线程简单实现

      1. 线程的创建

     1 from threading import Thread
     2 import time
     3 def sayhi(name):
     4     time.sleep(2)
     5     print('%s say hello' %name)
     6 
     7 if __name__ == '__main__':
     8     t=Thread(target=sayhi,args=('太白',))
     9     t.start()
    10     print('主线程')
    方式一
     1 import time
     2 from threading import Thread
     3 class Sayhi(Thread):
     4     def __init__(self,name):
     5         super().__init__()
     6         self.name=name
     7     def run(self):
     8         time.sleep(2)
     9         print('%s say hello' % self.name)
    10 
    11 
    12 if __name__ == '__main__':
    13     t = Sayhi('太白')
    14     t.start()
    15     print('主线程')
    方式二

      2. 线程的方法

     1 from threading import Thread
     2 import time
     3 def sayhi(name):
     4     time.sleep(2)
     5     print('%s say hello' %name)
     6 
     7 if __name__ == '__main__':
     8     t=Thread(target=sayhi,args=('太白',))
     9     t2=Thread(target=sayhi,args=('alex',))
    10     t.start()
    11     t2.start()
    12     t.join()  #因为这个线程用了join方法,主线程等待子线程的运行结束
    13 
    14     print('主线程')
    15     print(t.is_alive())  #所以t这个线程肯定是执行结束了,结果为False
    16     print(t2.is_alive()) #有可能是True,有可能是False,看子线程和主线程谁执行的快
    17     '''
    18     egon say hello
    19     主线程
    20     False
    21     '''
    join方法
     1 Thread实例对象的方法
     2   # isAlive(): 返回线程是否活动的。
     3   # getName(): 返回线程名。
     4   # setName(): 设置线程名。
     5 
     6 threading模块提供的一些方法:
     7   # threading.currentThread(): 返回当前的线程变量。
     8   # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
     9   # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果
    10 
    11 
    12 from threading import Thread
    13 import threading
    14 from multiprocessing import Process
    15 import os
    16 
    17 def work():
    18     import time
    19     time.sleep(3)
    20     print(threading.current_thread().getName())
    21 
    22 if __name__ == '__main__':
    23     #在主进程下开启线程
    24     t=Thread(target=work)
    25     t.start()
    26 
    27     print(threading.current_thread())#主线程对象
    28     print(threading.current_thread().getName()) #主线程名称
    29     print(threading.current_thread().ident) #主线程ID
    30     print(threading.get_ident()) #主线程ID
    31     print(threading.enumerate()) #连同主线程在内有两个运行的线程
    32     print(threading.active_count())
    33     print('主线程/主进程')
    34 
    35     '''
    36     打印结果:
    37     <_MainThread(MainThread, started 14104)>
    38     MainThread
    39     14104
    40     14104
    41     [<_MainThread(MainThread, started 14104)>, <Thread(Thread-1, started 17976)>]
    42     2
    43     主线程/主进程
    44     Thread-1
    45     '''
    其他方法

    二. 线程和进程效率对比

     1 from threading import Thread
     2 from multiprocessing import Process
     3 import os
     4 import time
     5 def work():
     6     print('hello')
     7 
     8 if __name__ == '__main__':
     9     s1 = time.time()
    10     #在主进程下开启线程
    11     t=Thread(target=work)
    12     t.start()
    13     t.join()
    14     t1 = time.time() - s1
    15     print('进程的执行时间:',t1)
    16     print('主线程/主进程')
    17     '''
    18     打印结果:
    19     hello
    20     进程的执行时间: 0.0
    21     主线程/主进程
    22     '''
    23 
    24     s2 = time.time()
    25     #在主进程下开启子进程
    26     t=Process(target=work)
    27     t.start()
    28     t.join()
    29     t2 = time.time() - s2
    30     print('线程的执行时间:', t2)
    31     print('主线程/主进程')
    32     '''
    33     打印结果:
    34     hello
    35     线程的执行时间: 0.5216977596282959
    36     主线程/主进程
    37     '''
    效率比较,线程快

    三. 查看子线程和主线程是否在同一进程

    # 查看子线程和主线程是否在同一个进程中
    from threading import Thread
    import os
    def fun():
        print('子线程的pid',os.getpid()) #获得当前 线程pid
    if __name__ == '__main__':
        t = Thread(target=fun,)
        t.start()
        print('主线程的pid',os.getpid()) #获得当前 pid  
    #结果是一样的,是同一进程里

    四. 线程之间的数据是共享的

    from threading import Thread
    def fun():
        global a
        a -= 1
    a = 10
    if __name__ == '__main__':
    
        t = Thread(target=fun,)
        t.start()
        t.join() # 加join 等待t 结束
        print(a) # 9 证明数据是共享的

    五. 验证多线程共享资源造成的数据不安全

    # 验证多线程共享资源造成的数据不安全的问题
    from threading import Thread
    import time
    def fun():
        global a
        t = a
        time.sleep(0.00001)
        t -= 1
        a = t
    a = 20
    if __name__ == '__main__':
        l = []
        for i in range(20):
            t = Thread(target=fun,)
            l.append(t)
            t.start()
        for i in l :
            i.join()
        print(a) # 18 

    六. 加锁解决共享数据不安全的问题

      锁(互斥锁同步锁) #Lock,解决数据共享是数据不安全的问题,

          但同时也牺牲了效率

      

     
     1 from threading import Thread,Lock
     2 import time
     3 def fun(l):
     4     l.acquire()
     5     global a
     6     t = a
     7     time.sleep(0.1)
     8     t -= 1
     9     a = t
    10     l.release()
    11 a = 20
    12 if __name__ == '__main__':
    13     l = []
    14     lock = Lock()
    15     for i in range(20):
    16         t = Thread(target=fun ,args=(lock,))
    17         l.append(t)
    18         t.start()
    19     for i in l:
    20         i.join()
    21     print(a)
    # 加锁解决共享数据不安全的问题

    七. 死锁现象

      死锁现象: 双方互相等待对方释放对方手里拿到的那个锁

      

     1 from threading import Thread ,Lock
     2 import time
     3 
     4 def fun1(lock_A,lock_B):
     5     lock_A.acquire()
     6     time.sleep(1)
     7 
     8     print('A抢到了锁a')
     9     lock_B.acquire()
    10     print('A抢到了锁b')
    11     lock_B.release()
    12     lock_A.release()
    13 def fun2(lock_A,lock_B):
    14     lock_B.acquire()
    15     print('B抢到了b锁')
    16     lock_A.acquire()
    17     print('B抢到了a锁')
    18     lock_A.release()
    19     lock_B.release()
    20 if __name__ == '__main__':
    21     lock_A = Lock()
    22     lock_B = Lock()
    23     t1 = Thread(target=fun1,args=(lock_A,lock_B))
    24     t2 = Thread(target=fun2,args=(lock_A,lock_B))
    25     t1.start()
    26     t2.start()
    死锁现象

    八. 解决死锁, 使用递归锁

      同样是互斥,里面存着个计数器

      进程的死锁和线程的是一样的,而且一般情况下进程之间是数据不共享的,

    不需要加锁,由于线程是对全局的数据共享的,所以对于全局的数据进行操作的时候,要加锁.

    import time
    from threading import Thread,RLock
    fork_lock = noodle_lock = RLock()
    def eat1(name):
        noodle_lock.acquire()
        print('%s 抢到了面条'%name)
        fork_lock.acquire()
        print('%s 抢到了叉子'%name)
        print('%s 吃面'%name)
        fork_lock.release()
        noodle_lock.release()
    
    def eat2(name):
        fork_lock.acquire()
        print('%s 抢到了叉子' % name)
        time.sleep(1) 
        noodle_lock.acquire()
        print('%s 抢到了面条' % name)
        print('%s 吃面' % name)
        noodle_lock.release()
        fork_lock.release()
    
    for name in ['taibai','wulaoban']:
        t1 = Thread(target=eat1,args=(name,))
        t1.start()
    for name in ['alex','peiqi']:
        t2 = Thread(target=eat2,args=(name,))
        t2.start()
    View Code

    九. 守护线程

      守护线程: 主线程等着进程中所有非守护线程的结束,才算结束

      守护进程: 主进程代码结束, 守护进程跟着结束

     1 # 守护线程
     2 from threading import Thread
     3 import time
     4 from multiprocessing import Process
     5 
     6 def fun1():
     7     time.sleep(3)
     8     print(111111111111)
     9 def fun2():
    10     time.sleep(2)
    11     print(222222222222)
    12 if __name__ == '__main__':
    13     # p1 = Process(target=fun1, )
    14     # p2 = Process(target=fun2, )
    15     # p2.daemon = True
    16     # # p1.daemon = True
    17     # p1.start()
    18     # p2.start()
    19 
    20     t1 = Thread(target=fun1,)
    21     t2 = Thread(target=fun2,)
    22     t2.daemon = True
    23     # t1.daemon = True
    24     t1.start()
    25     t2.start()
    26 
    27 
    28     print('结束')
    守护线程和守护进程的区别

    十. 信号量

     1 # 信号量
     2 import time,random
     3 from multiprocessing import Process,Semaphore
     4 from threading import Thread,Semaphore
     5 def fun(i,s):
     6     s.acquire()
     7     time.sleep(random.randint(1,3))
     8     print('%s号来了' %i)
     9     s.release()
    10 
    11 if __name__ == '__main__':
    12     s = Semaphore(4)
    13     for i in range(10):
    14         t = Thread(target=fun,args=(i,s)) # 线程守护
    15         t.start()
    16 
    17     # s = Semaphore(4)    
    18     # for i in range(10):
    19     #     p = Process(target=fun,args=(i,s))   #进程守护
    20     #     p.start()
    守护线程

    十一. 事件

     1 from threading import Thread,Event
     2 e = Event() #默认状态False
     3 print(1)
     4 e.set() #设置状态为True
     5 print(e.is_set()) #查看状态
     6 e.clear() # 设置状态 False
     7 print(e.is_set()) #查看状态
     8 e.set()  #设置状态
     9 print(e.is_set()) #查看状态
    10 e.wait() #判断 等 False  走True
    11 print('结束')
    事件
  • 相关阅读:
    Jmeter 接口测试实战-有趣的cookie
    Jmeter输出完美报告
    记忆-走进古镇
    JMeter接口测试实战-动态数据验证
    JMeter写入文件
    正则表达式匹配任意字符(包括换行符)
    No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android"
    Unable to get the CMake version located at
    adb 查看 android手机的CPU架构
    java.lang.UnsatisfiedLinkError:dlopen failed: “**/*/arm/*.so” has unexpected e_machine: 3
  • 原文地址:https://www.cnblogs.com/Thui/p/10045995.html
Copyright © 2011-2022 走看看