python多进程笔记3 - 共享内存,信号量,时间,socket,进程池

本文通过实例详细介绍了Python中的多进程操作,包括信号量的使用确保资源访问控制,事件的等待与设置实现进程间的同步,Socket通信的服务器端与客户端实现,以及如何利用共享内存进行数据交换。最后,通过对比展示了进程池的同步和异步应用,阐述了其在并行计算中的效率优势。
摘要由CSDN通过智能技术生成
20171107 - thread - day3


知识总结:
资源使用之后需要关闭或者释放,否则资源会处于泄露的状态;
一般情况下 父进程会等子进程结束再结束;
互斥量锁的添加原则:粒度最小原则
google浏览器:ctrl + f 界面搜索


进程池中的同步方法,执行流程与单进程相似,是阻塞的执行,时间更长;
进程池中的异步方法,是多进程的,并行执行,效率高,时间更短。


全局变量,子进程可以访问和修改(子进程拷贝全局变量后再修改,然后给自己用)全局变量,但是自己改的数据只能自己用;
如果创建了共享内存(数组,value),所有子进程就可以访问和修改全局变量,并且工大家使用,但会出现资源抢占导致资源修改错误(对于同一个文件,一个写,另一个也在写,一个要保存,结果被另外一个人保存和退出,那么这里两个人的这两次操作都算结束)的事情发生,所以一定要加锁。
简而言之,每个进程拥有自己的全局变量,互补干扰。


=====================================================================


1.共享内存:
    允许多个进程使用相同的内存,一个进程改变其中的数据后,其他的进程都可以看到数据的变化;
   速度快的原因,省略了正常内存中进程间通信的拷贝次数,由4次变为2次;没有数据序列话的过程;
   优点:在进程间快速高效的传递数据;
   缺点:内存共享导致资源抢占,同一时间只有一个进程在执行或者 写 或者 读 的操作;


=====================================================================


2.信号量-阿姨准备咖啡:


    可以同时提供给N个消费者服务,互斥量其实是一种特殊的信号量,特殊在一次只有一个消费者;


实例:
import multiprocessing
import time


def consumer(s):
    s.acquire()   #信号量的使用与互斥量类似
    print(multiprocessing.current_process().name+'get')
    time.sleep(1)
    s.release()
    print(multiprocessing.current_process().name+'release')


if __name__ == '__main__':
    s = multiprocessing.Semaphore(2)    
               #把信号量值设置为2,一次提供给两个消费者服务
    for i in range(5):    #启5个进程
        p = multiprocessing.Process(target=consumer,args=(s,))
        p.start()
    print('main end')


执行结果:
tarena@tedu:~/aid1709/thread$ python3 thread03_20171107.py 
Process-1get
Process-2get
main end
Process-2release
Process-1release
Process-4get
Process-3get
Process-4release
Process-5get
Process-3release
Process-5release


=====================================================================


3.事件:Event(通知做事)
方法:
In [3]: s = multiprocessing.Event()
In [4]: s.
s.clear   s.is_set  s.set     s.wait    


一个进程通过Event通知另一个进程做某件事件的时机到了,我们就可以做这件事了。
一个写的程序在多个读的进程中,可以通过这种方式来通知这些进程们,可以来读数据了。
e.wait([timeout]),e.set()




实例:
import multiprocessing
import time


def wait_for_event(e):
    print('wait for event:starting')
    e.wait() #一直阻塞等待
    print('wait for event is_set:'+ str(e.is_set()))


def wait_for_event_time(e,t):
    print('wait for timeout:starting')
    e.wait(t) #定时阻塞等待
    print('wait for event timeout is_set:'+ str(e.is_set()))


if __name__ == '__main__':
    e = multiprocessing.Event()  #创建一个事件


    #创建两个进程,第一个是阻塞,第二个是非阻塞,第二个进程会等待两秒的信号量
    w1 = multiprocessing.Process(name='block',target = wait_for_event,args=(e,))
    w2 = multiprocessing.Process(name='non-block',target = wait_for_event_time,args=(e,2)) #睡眠2秒,主进程3秒


    w1.start()
    w2.start()
    time.sleep(3)  #主进程
    e.set()   #主进程先睡3秒,通知事件  将内部标志设置为true。
              #所有等待它成为真的线程都被唤醒
    print('main event is set')


执行结果:
tarena@tedu:~/aid1709/thread$ python3 thread03_20171107.py 
wait for event:starting
wait for timeout:starting
wait for event timeout is_set:False
wait for event is_set:True
main event is set




=====================================================================


4.socket


#演示socket - 模拟服务端
from socket import *
import time


s = socket(AF_INET,SOCK_STREAM)
s.bind(('',8081))
s.listen(5)
while True:
    client,addr = s.accept()
    print('got a connection from %s' % str(addr))
    timestr = time.ctime(time.time())+'\r\n'
    client.send(timestr.encode('ascii'))
    client.close()


#------------------------------


#演示socket - 模拟客户端
from socket import *
import time


s = socket(AF_INET,SOCK_STREAM)
s.connect(('localhost',8081))
tm = s.recv(1024)
s.close()
print('The time is %s' % tm.decode('ascii'))


=====================================================================


5.共享内存(value-array)


#演示共享内存 - 共享数组
import multiprocessing
from datetime import datetime


def trans(a,size):
    t = datetime.now()
    for i in range(size):
        print(a[i])
    print('消耗了%s' % (datetime.now()-t))


if __name__ == '__main__':
    print('test share memory')  #在两个进程之间 建立共享内存 - 数组
    num = 10
    a = multiprocessing.Array('i',num)  #数组的类型 int 数组的长度是10,默认的元素为0
    p = multiprocessing.Process(target = trans,args = (a,num))#创建进程 将共享数组和长度传递给进程
    
    p.start()
----------------------------------------


全局变量不共享 演示


from multiprocessing import Process
import time


g_num = 100
def getTime(interval):
    global g_num
    while True:
        g_num += 100
        time.sleep(interval)
        print("in child num is %d"%g_num)


if __name__ == '__main__':
    p = Process(target=getTime, args=(2,))
    p.start()


    while True:
        g_num += 1
        print("Current num is %d"%g_num)
        time.sleep(1)


tarena@tedu:~/aid1709/thread_1104_1108$ python3 thread_1108.py 
Current num is 101
Current num is 102
Current num is 103
in child num is 200
Current num is 104
in child num is 300
Current num is 105
Current num is 106
in child num is 400
Current num is 107
Current n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值