进程、协程

进程

#进程调用跟线程差不多
#方法一:
# from multiprocessing import Process
# import time
# def test(name):
#     time.sleep(1)
#     print("hello",name,time.ctime())
#
# if __name__ == '__main__':
#     p_list=[]
#     for i in range(3):
#         p=Process(target=test,args=("alex",))
#         p_list.append(p)
#         p.start()
#     for i in p_list:
#         i.join()
#     print("end...")


#方法二:
# from multiprocessing import Process
# import time
# class MyProcess(Process):
#     def run(self):
#         time.sleep(1)
#         print("hello",self.name,time.ctime())
#
# if __name__ == '__main__':
#     p_list=[]
#     for i in range(3):
#         p=MyProcess()
#         p_list.append(p)
#         p.start()
#     for i in p_list:
#         i.join()
#     print("end...")


#守护进程
# from multiprocessing import Process
# import time
# class MyProcess(Process):
#     def run(self):
#         time.sleep(1)
#         print("hello",self.name,time.ctime())
#
# if __name__ == '__main__':
#     p_list=[]
#     for i in range(3):
#         p=MyProcess()
#         p.daemon=True       #子进程跟着主进程结束
#         p.start()
#         p_list.append(p)
#     # for i in p_list:
#     #     i.join()
#     print("end...")
#结果只打印一个end...


from multiprocessing import Process
import time,os
def info(title):
    print("title",title)
    print("parent process:",os.getppid())    #父进程
    print("process id:",os.getpid())         #这个进程本身
def f(name):
    info('function f')
    print("hello",name)

if __name__ == '__main__':
    info("main process line")
    print("---------------------------------")
    p=Process(target=info,args=('子进程',))
    p.start()
    p.join()
View Code

 

进程池

#进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序
#就会等待,直到进程池中有可用进程为止

# 进程池的两个方法:
# apply         同步
# apply_async   异步

import time
from multiprocessing import Process,Pool
def Foo(i):
    time.sleep(1)   #隔一秒
    print(i)
    # return "hello %s" % i

#回调函数
def Bar(arg):                    #这里的arg是Foo的return结果
    # print(arg)
    print("--------callback---------")

if __name__ == '__main__':
    pool=Pool(5)        #五个五个出来,不填的话CPU是几核默认就执行多少
    # pool=Pool()        #4个,因为是四核
    for i in range(50):
        # pool.apply(func=Foo,args=(i,))  #同步接口,一个一个打印
        # pool.apply_async(func=Foo,args=(i,))    #异步接口
        #回调函数: 就是某个动作或者函数执行完才执行回调函数
        pool.apply_async(func=Foo,args=(i,),callback=Bar)   #回调函数优点:需要主进程执行,不要子进程执行的时候
    pool.close()    #先close再join,顺序是固定的
    pool.join()
    print("end...")
View Code

 

协程

#复习yield生成器。
# def Foo():
#     print("ok1")
#     s5=yield 1
#     print(s5)   #send过来的
#     print("ok2")
#     yield
# gen=Foo()
# y=next(gen)   #ok1
# print(y)      #1
# gen.send(5)    #把5给了yield

# 并发的本质:切换+保存状态
# 协程:写作式,-----------非抢占式的程序,可以指定去执行某个程序
#         A---->B---->A--->C

        # yield 协程
        #用户态的切换
        #key:什么时候切换!
        #协程主要解决的也是IO操作
        #本质上就是一个线程
        #优势:
            #1.没有切换的消耗
            #2.没有锁的概念
        #问题:能用多核吗?  可以采用多进程+协程,一个解决并发的方案


#Gleenlet

# from greenlet import greenlet
# def eat(name):
#     print('%s eat 1' %name)
#     g2.switch('egon')
#     print('%s eat 2' %name)
#     g2.switch()
# def play(name):
#     print('%s play 1' %name)
#     g1.switch()
#     print('%s play 2' %name)
#
# g1=greenlet(eat)
# g2=greenlet(play)
#
# g1.switch('egon')#可以在第一次switch时传入参数,以后都不需要



#gevent

#下例gevent.sleep(2)模拟的是gevent可以识别的io阻塞,time.sleep的话需要打补丁
#from gevent import monkey;monkey.patch_all()必须放到被打补丁者的前面,或者文件开头
# import gevent
# def eat(name):
#     print('%s eat 1' % name)
#     gevent.sleep(2)
#     print('%s eat 2' % name)
# def play(name):
#     print('%s play 1' % name)
#     gevent.sleep(1)
#     print('%s play 2' % name)
# g1=gevent.spawn(eat,'egon')
# g2=gevent.spawn(play,'egon')
# g1.join()
# g2.join()
# print("")
View Code

 

posted @ 2019-05-08 23:51  rayh  阅读(81)  评论(0)    收藏  举报