zoukankan      html  css  js  c++  java
  • python学习第32天

    一. Manager

    进程之间的共享数据(列表list 或者 字典dict等)

    from multiprocessing import Process,Manager,Lock
    
    def work(data,lock):
       # 1.正常写法
       """
       lock.acquire()
       # data["count"] -= 1
       data[0] += 1
       lock.release()
       """
       
       # 2.使用with 语法简化上锁解锁操作
       with lock:
          data[0] += 1
       
    if __name__ == "__main__":
       m = Manager()
       # 创建一个共享的字典
       data = m.dict( {"count":20000} )
       # 创建一个共享的列表
       data = m.list([1,2,3])
       
       # print(data)
       
       lst = []
       lock = Lock()
       for i in range(100):
          p = Process(target=work,args=(data,lock))
          p.start()
          lst.append(p)
          
       # 确保所有的进程执行完毕,然后在向下运行,打印数据,否则报错;
       for i in lst:
          i.join()
          
       print(data) # [101, 2, 3]
    

    二. 线程

    #进程是资源分配的最小单位
    #线程是计算机中调度的最小单位
    
    #线程的缘起
    资源分配需要分配内存空间,分配cpu:
    分配的内存空间存放着临时要处理的数据等,比如要执行的代码,数据
    而这些内存空间是有限的,不能无限分配
    目前配置高的主机,5万个并发已是上限.线程概念应用而生.
    
    #线程的特点
    线程是比较轻量级,能干更多的活,一个进程中的所有线程资源是共享的.
    一个进程至少有一个线程在工作
    

    1 . 一份进程资源中可以包含多个线程

    from threading import Thread
    from multiprocessing import Process
    import os
    
    """
    def func(num):
       print('当前线程{},所归属的进程id号{}'.format(os.getpid(),num))
    
    for i in range(10):
       # 异步创建10个子线程
       t = Thread(target=func,args=(i,))
       t.start()
    
    # 主线程执行任务
    print(os.getpid())
    

    2 . 并发多线程和多进程, 多线程的速度更快,谨慎选择创建进程的数量

    import time
    
    def func(num):
       print('当前线程{},所归属的进程id号{}'.format(os.getpid(),num))
    
    if __name__=='__main__':
    
       """
       #记录开始时间
       starttime=time.time()
    
       lst=[]
       for i in range(1000):
          t=Thread(target=func,args=(i,))
          t.start()
          lst.append(t)
    
       # 等到所有子线程执行完毕
       for i in lst:
          i.join()
          
       # 记录结束时间
       endtime=time.time()
    
       print("多线程执行时间:",endtime-starttime)
       """
       
       """
       #记录开始时间
       starttime=time.time()
    
       lst=[]
       for i in range(1000):
          p=Process(target=func,args=(i,))
          p.start()
          lst.append(p)
    
       # 等到所有子线程执行完毕
       for i in lst:
          i.join()
          
       # 记录结束时间
       endtime=time.time()
    
       print("多进程执行时间:",endtime-starttime)
    

    3 .多线程共享同一份进程资源

    num =1000
    def func():
       global num
       num -=1
    
    for i in range(1000):
       t=Thread(target=func)
       t.start()
    
    print(num)
    

    4 . 用自定义类的方法创建线程

    一定要继承父类Thread

    手动调用父类的构造方法

    class MyThread(Thread):
       def __init__(self,name):
          # 手动调用父类的构造方法
          super().__init__()
          self.name = name
    
       def run(self):
          time.sleep(1)
          print("当前进程正在执行runing ... " , self.name)
          
    if __name__ == "__main__":
       t = MyThread("机器今天会再次爆炸么?")
       t.start()
       print("主线程执行结束 ... ")
    
    

    5 . 线程相关的函数

    线程.is_alive()    检测线程是否仍然存在
    线程.setName()     设置线程名字
    线程.getName()     获取线程名字
    1.currentThread().ident 查看线程id号 
    2.enumerate()        返回目前正在运行的线程列表
    3.activeCount()      返回目前正在运行的线程数量
    
    def func():
       time.sleep(1)
    if __name__ == "__main__":
       t = Thread(target=func)
       
       # print(t)
       t.start()
       # print(t , type(t))
       print(t.is_alive()) # False
       print(t.getName())
       t.setName("xboyww")
       print(t.getName())
    

    currentThread().ident 查看线程id号

    def func():
       print("子线程id",currentThread().ident  , os.getpid())
    
    if __name__ == "__main__":
       Thread(target=func).start()
       print("主线程id",currentThread().ident , os.getpid())
    

    enumerate() 返回目前正在运行的线程列表

    acctiveCount() 返回目前正在运行的线程数量

    from threading import enumerate
    from threading import activeCount # (了解)
    def func():
       print("子线程id",currentThread().ident  , os.getpid())
       time.sleep(0.5)
       
    if __name__ == "__main__":
       for i in range(10):
          Thread(target=func).start()
       lst = enumerate()
       # 子线程10 + 主线程1个 = 11
       # print(lst ,len(lst))
       
       # 3.activeCount()      返回目前正在运行的线程数量
       print( activeCount() )
    

    6 .守护线程

    等待所有线程全部执行完毕之后,在自己终止,守护的是所有线程

    线程名.setDaemon(True)

    from threading import Thread
    import time
    def func1():
       while True:
          time.sleep(0.5)
          print("我是func1")
       
    def func2():   
       print("我是func2 start ... ")
       time.sleep(3)
       print("我是func2 end ... ")
       
    t1 = Thread(target=func1)
    t2 = Thread(target=func2)
    
    # 在start调用之前,设置守护线程
    t1.setDaemon(True)
    
    t1.start()
    t2.start()
    
    print("主线程执行结束 ... ")
    

    7 . 用 Lock 保证数据安全

    from threading import Lock,Thread
    import time
    n = 0
    
    def func1(lock):
       global n
       
       lock.acquire()
       for i in range(1000000):
          # 方法一     
          n -= 1
       lock.release()
       
    def func2(lock):
       global n
       # with 自动完成上锁+解锁
       with lock:
          for i in range(1000000):
             # 方法二           
             n += 1
    
    # func1()
    # func2()
    # print(n)
    if __name__ == "__main__":
       lst = []
       lock = Lock()
       
       time1 = time.time()
       for i in range(10):
          t1 = Thread(target=func1,args=(lock,))
          t2 = Thread(target=func2,args=(lock,))
          t1.start()
          t2.start()
          lst.append(t1)
          lst.append(t2)
          
       # 等待所有的子线程执行结束之后, 在打印数据
       for i in lst:
          i.join()
         
       time2 = time.time()
       print("主线程执行结束..." , n ,time2 - time1)
    

    8 . 信号量 Semaphore(线程)

    from threading import Semaphore,Thread
    import time
    
    def func(i,sm):
       with sm:
          print(i)
          time.sleep(3)
    
    if __name__ == "__main__":
       sm = Semaphore(5)
       for i in range(20):
          Thread(target=func,args=(i,sm)).start()
    
    """
    总结:
    在创建线程的时候是异步创建
    在执行任务的时候,因为Semaphore加了锁,所以线程之间变成了同步
    """
    
  • 相关阅读:
    自定义Collection类
    基本排序算法(冒泡排序,选择排序,插入排序)
    泛型
    XSD的学习
    SSH整合配置
    一个可以随时插入的json的简单实现
    将Properties文件的键值对调换位置重新生成一个文件
    JAVA MD5加密
    框架中退出登录
    java 生成 xml
  • 原文地址:https://www.cnblogs.com/yunchao-520/p/13096736.html
Copyright © 2011-2022 走看看