Python的Socket知识8:进程、数据共享、进程池

     进程(process)是cpu资源分配的最小单位,线程(thread)是cpu调度的最小单位。多线程和多进程的应用目的是为了提高并发。一个应用程序可以包含多个进程,而一个进程又可以包含多个线程。默认一个应用程序是单进程、单线程。

    主要讲解创建进程的方法,以及实现共享的方式。

1、基本使用方法:

案例1:创建进程

from multiprocessing import Process
def foo(i):
    print("hh",i)
if __name__ == '__main__':#在Windows下,此语句只能做测试用,不用在生产中用
    li=[]
    for i in range(10):
        p=Process(target=foo,args=(i,))
        p.start()

执行结果:

进程同样有daemon和join方法,类似于线程

案例2:join() 也适用在进程中,逐个执行进程

    当一个线程操作需要等待另一个线程执行完毕之后才能继续进行时,使用Join()方法。Join方法会等到使用该方法的线程结束后再执行下面的代码

from multiprocessing import Process
def foo(i):
    print("hh",i)
if __name__ == '__main__':#在Windows下,此语句只能做测试用,不用在生产中用
    li=[]
    for i in range(10):
        p=Process(target=foo,args=(i,))
        p.start()
        p.join(5)#逐个执行每个进程,执行完毕后,继续往下执行
    print('123')

执行结果:

2、数据共享:

进程之间默认数据不共享,比如QQ和百度就不会共享数据,可以通过一些方法实现数据共享

案例3:不共享的案例。

from multiprocessing import Process
import time
def foo(i,arg):
    arg.append(i)
    print("hh",i,arg)
if __name__ == '__main__':#在Windows下,此语句只能做测试用,不用在生产中用
    li=[]
    for i in range(10):
        p=Process(target=foo,args=(i,li))
        p.start()

执行结果:如果共享,则中括号中的数据i应该从0开始排列

案例4,利用queues,实现进程的共享

from multiprocessing import Process
from multiprocessing import queues#特殊的功能,实现进程之间数据共享
import multiprocessing
def foo(i,arg):
    arg.put(i)
    print("hh",i,arg.qsize())
if __name__ == '__main__':#在Windows下,此语句只能做测试用,不用在生产中用
    li=queues.Queue(20,ctx=multiprocessing)
    for i in range(10):
        p=Process(target=foo,args=(i,li))
        p.start()

执行效果:

案例5,利用array实现数据共享

from multiprocessing import Process, Array
def Foo(i,arg):
    arg[i] = 100 + i
    for item in arg:
        print ('----->',item)
    print('================')
if __name__ == '__main__':
    li=Array('i',10)
    for i in range(10):
        p = Process(target=Foo, args=(i,li,))
        p.start()

执行效果:

案例6,利用manage实现数据共享

from multiprocessing import Process
from multiprocessing import Manager
def foo(i,arg):
    arg[i] = i+100
    print(arg.values())
if __name__ == '__main__':
    obj=Manager()
    li=obj.dict()
    for i in range(10):
        p = Process(target=foo,args=(i,li,))
        p.start()
        p.join()#控制子进程,或者用下面的time来控制主进程不终止
    # import time
    # time.sleep(0.1)

执行效果:

3、进程锁、条件、事件等,同线程锁用法

案例7:进程锁:同线程锁的用法

from multiprocessing import Process,Array,RLock
import time
def foo(i,arg,lc):
    lc.acquire()
    arg[0]=arg[0]-1
    time.sleep(1)
    print("say hi",arg[0])
    lc.release()
if __name__ == '__main__':
    li=Array('i',1)
    li[0]=10
    lock=RLock()
    for i in range(10):
        p = Process(target=foo,args=(i,li,lock,))
        p.start()

执行结果:

4、进程池:

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

案例8:apply串行的方式执行

from multiprocessing import Pool
import time

def foo(arg):
    time.sleep(1)
    print("say hi",arg)

if __name__ == '__main__':
    pool=Pool(5)
    for i in range(10):
        pool.apply(func=foo,args=(i,))#串行的方式执行
    print("end")

执行结果:

案例9:apply_async主进程执行完,不等子进程

from multiprocessing import Pool
import time

def foo(arg):
    time.sleep(1)
    print("say hi",arg)

if __name__ == '__main__':
    pool=Pool(5)
    for i in range(10):
        # pool.apply(func=foo,args=(i,))#串行的方式执行
        pool.apply_async(func=foo,args=(i,))#主进程执行完,不等子进程
    print("end")

执行结果:end

案例10:teminate和close的终止方式

from multiprocessing import Pool
import time

def foo(arg):
    time.sleep(1)
    print("say hi",arg)

if __name__ == '__main__':
    pool=Pool(5)
    for i in range(10):
        pool.apply_async(func=foo,args=(i,))#串行的方式执行
    pool.close()#所有的任务全部执行完,进程继续执行
    #pool.terminate()  #执行到此,立即终止
    pool.join()

5、协程:

    协程是一种用户态的轻量级线程,其实可以认为是比线程更小的执行单元。利用一个线程,分解一个线程成为多个"微线程"。

    协程存在的意义:线程切换从系统层面远不止 保存和恢复 CPU上下文这么简单。操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。

    协程的适用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程;

http://blog.csdn.net/qq910894904/article/details/41699541

案例11:协程gevent的应用

from gevent import monkey;monkey.patch_all()
import gevent
import requests
def f(url):
    print('GEt:%s'%url)
    resp=requests.get(url)
    data=resp.text
    print("%d bytes received from %s"%(len(data),url))
gevent.joinall([
        gevent.spawn(f,'https://www.python.org'),
        gevent.spawn(f,'https://www.baidu.com'),
        gevent.spawn(f,'https://www.cnblogs.com/'),
                ])

执行结果:

案例链接:https://pan.baidu.com/s/1snibPi1 密码:jh96

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值