进程,线程与协程

539 阅读3分钟

多进程

几乎和多线程一模一样,但是耗费资源较大,所以不是越多越好

import time 
import multiprocessing

def test1():
  while True:
    print('1-------------')
    time.sleep(1)


def test2():
  while True:
    print('2-------------')
    time.sleep(1)
  

def main():
  p1 = multiprocessing.Process(target=test1)
  p2 = multiprocessing.Process(target=test2)
  p1.start()
  p2.start()


if __name__ == '__main__': 
    main()
    

![image-20200502115746746](# 迭代器

from collections import Iterable,Iterator
import time
# class classIterator():
#     def __init__(self,obj):
#         self.obj = obj
#         self.current_num = 0
#     def __iter__(self):
#         pass
    
#     def __next__(self):
#         if self.current_num<len(self.obj.names):
#             ret = self.obj.names[self.current_num]
#             self.current_num+=1
#             return ret
#         else:
#             raise StopIteration


class Classmate(object):
    def __init__(self):
        self.names = list()
        self.current_num = 0
    
    def add(self,name):
        self.names.append(name)

    def __iter__(self):
        """
        如果想让一个对象可以迭代,即使用for,那么必须实现__iter__方法
        """  
        return self
    def __next__(self):
        if self.current_num<len(self.names):
            ret = self.names[self.current_num]
            self.current_num+=1
            return ret
        else:
            raise StopIteration

classmate = Classmate()
classmate.add('老王')
classmate.add('老王2')
classmate.add('老王3')


# classmate_iterator = iter(classmate) 
# print('判断classmate是否可以迭代:',isinstance(classmate,Iterable))
# print('判断classmate是否是迭代器:',isinstance(classmate_iterator,Iterator))
# print(next(classmate_iterator)) # * 手动迭代

for name in classmate: 
    print(name)
    time.sleep(1)

生成器

生成器是特殊的迭代器

第一种方式

image-20200502220300169

[x*2 for x in range(10)]可以生成list
把中括号换成小括号就变成迭代器了
list占空间,但迭代器只是记录生成数据的方式,占用空间不大,这就是迭代器相对于list的优点

第二种方式

函数中包含yield

greenlet是yield的升级版/image-20200502115746746.png)

进程之间通信

使用队列queue

image-20200502123026790

进程池

程序创建和销毁需要大量的资源,如果使用进程池可以减少创建和销毁,实现重复利用

image-20200502135756645

线程

通过函数创建线程(可以查看线程数)

import time
import threading


def sing():
    for i in range(5):
        print('singing')
        time.sleep(1)


def dance():
    for i in range(0, 10):
        print('dancing')
        time.sleep(1)



def main():
    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)
    t1.start()
    t2.start() 
    while  True:
      print(threading.enumerate(),len(threading.enumerate()))
      time.sleep(1)
      if len(threading.enumerate()) <=1:
        print(threading.enumerate(),len(threading.enumerate()))
        print('程序结束')
        break
    


if __name__ == '__main__':
    main()

函数传参

image-20200502010805542

通过class创建对象创建线程

image-20200502001257686

run方法一定要定义,在start的时候run方法会被执行,这种在类使用线程的方法适合于复杂的使用线程的情况,比如使用多个函数来使用线程,当然也可以传参

from time import * 
import threading


class setInterval(threading.Thread):
  
  def __init__(self,func,time):
    super().__init__()
    self.time = time
    self.bool = True
    self.func =func
    self.i =0

  def stop(self):
    print('结束')
    self.bool = False

  def run(self):
    while self.bool:
      sleep(1)
      self.func()
      
def myfunc():
  print('test')
t = setInterval(myfunc,1)
t.start()

def clearInterval(t):
  t.stop()

sleep(5)
clearInterval(t)

多个线程是共享全局变量

当然了 ,全局变量所有函数都能访问,这还要什么解释

共享存在的问题(资源竞争)

多个线程同时处理全局变量会出现问题,如果两个以上同时处理一个全局变量可能会有其中一个失效

解决方案---互斥锁

image-20200502013203987

上锁的代码越少越好

image-20200502013558327

协程

迭代器

from collections import Iterable,Iterator
import time
# class classIterator():
#     def __init__(self,obj):
#         self.obj = obj
#         self.current_num = 0
#     def __iter__(self):
#         pass
    
#     def __next__(self):
#         if self.current_num<len(self.obj.names):
#             ret = self.obj.names[self.current_num]
#             self.current_num+=1
#             return ret
#         else:
#             raise StopIteration


class Classmate(object):
    def __init__(self):
        self.names = list()
        self.current_num = 0
    
    def add(self,name):
        self.names.append(name)

    def __iter__(self):
        """
        如果想让一个对象可以迭代,即使用for,那么必须实现__iter__方法
        """  
        return self
    def __next__(self):
        if self.current_num<len(self.names):
            ret = self.names[self.current_num]
            self.current_num+=1
            return ret
        else:
            raise StopIteration

classmate = Classmate()
classmate.add('老王')
classmate.add('老王2')
classmate.add('老王3')


# classmate_iterator = iter(classmate) 
# print('判断classmate是否可以迭代:',isinstance(classmate,Iterable))
# print('判断classmate是否是迭代器:',isinstance(classmate_iterator,Iterator))
# print(next(classmate_iterator)) # * 手动迭代

for name in classmate: 
    print(name)
    time.sleep(1)

生成器

生成器是特殊的迭代器

第一种方式

image-20200502220300169

[x*2 for x in range(10)]可以生成list
把中括号换成小括号就变成迭代器了
list占空间,但迭代器只是记录生成数据的方式,占用空间不大,这就是迭代器相对于list的优点

第二种方式

函数中包含yield

greenlet是yield的升级版