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

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 num is 108
in child num is 500
Current num is 109
....


主进程和子进程拥有自己的全局变量,各自访问和使用,互不干扰。
=====================================================================


6.进程池
预先创建一组子进程,当有新任务来的时候,主进程通过某个方式分配给该数组进程中的一个进程来完成此任务。


优势:
进程创建、销毁需要cpu的时间开销;
预先创建,以空间换时间,提供性能;
通过合理分配任务,可以提高性能(python进程池的map机制)


创建进程池:
python进程池实现——pool:方便对多个函数或分布式数据并行执行和运算
from muliprocessing import Pool


注意:
pool类必须有 __mian__模块导入;
进程池对象的方法只能有创建进程池的进程池调用


apply(func[,args[,kwds]]) 同步
apply_async 异步


进程池:
fork   子进程,父进程(父进程不会等子进程,抛弃父子关系),父子进程都做事情
process  父进程会等待子进程,父子进程都要做事情
Pool     父进程等子进程,父进程不做事情(先close 后join)


p = Pool()
p.apply_async()  p.map()
p.close
p.join()
p.apply 不要用,实际类似单进程,阻塞执行,可能比单进程慢


from multiprocessing import Pool
p = Pool()  #默认会建立子进程数与cpu核数相同的进程池




实例1:
from multiprocessing import Pool
import time


def Cal(n):
    sum = 0
    for i in range(n):
        sum += i*i
    return sum


if __name__ == '__main__':


    calCount = 10000  #计算到calCount-1 平方和
    check = 1001  #验证加到此时的平方和


    t1 = time.time()   #用进程池算平方和
    p = Pool()
    result = p.map(Cal,range(calCount))  #计算到0 到9999的平方和
    p.close()
    p.join()#进程池一定要有join方法,等子进程们结束再结束
    
    print(result[check])
    print('进程池花费时间:%f' % (time.time() - t1))






    t2 = time.time() #用单个进程做平方和,查看计算的时间
    result2 =[]
    for x in range(calCount):
        result2.append(Cal(x))
    print(result2[check])
    print('进程池花费时间:%f' % (time.time() - t2))




执行结果:
tarena@tedu:~/aid1709/thread$ python3 shiyan.py
333833500
进程池花费时间:2.042295
333833500
进程池花费时间:3.784239


------------------------------------------------------------
演示 进程池 - apply同步(我)运行 - 阻塞式运行,类似单线程(几乎不用)




from multiprocessing import Pool
import time
import os


def func(str):
    print ("Pool:", str)
    print('当前的子进程的id是:%d' % (os.getpid()))
    time.sleep(3)
    print ("Pool:", str, "end",'\n')


if __name__ == "__main__":
    p = Pool(processes = 3)
    time1 = time.time()# 进程池中有3个进程,但是有4个任务,
    for i in range(4):
        
        msg = "apply %d" %(i)
        p.apply(func, (msg, ))  
 
    
    p.close()# close 必须在join之前
    p.join()# join阻塞等待
    print ("Main end")
    print(time.time() - time1)


tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
Pool: apply 0
当前的子进程的id是:20070
Pool: apply 0 end 


Pool: apply 1
当前的子进程的id是:20069
Pool: apply 1 end 


Pool: apply 2
当前的子进程的id是:20071
Pool: apply 2 end 


Pool: apply 3
当前的子进程的id是:20070
Pool: apply 3 end 


Main end
12.116149425506592


----------------------------------------------------------------
演示 进程池 - apply_async异步(我与京东)运行 - 非阻塞式运行


from multiprocessing import Pool
import time


def func(str):
    print ("Pool:", str)
    time.sleep(3)
    print ("Pool:", str, "end")


if __name__ == "__main__":
    pool = Pool(processes = 3)  #3个子进程 4个任务
    time1 = time.time();
    for i in range(4):
        msg = "apply_async %d" % (i)
        pool.apply_async(func, (msg, ))   


    #print ("for end")


    pool.close()# close 必须在join之前
    pool.join()# join阻塞等待 
    print ("Main end")
    print(time.time() - time1)




tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
Pool: apply_async 0
Pool: apply_async 1
Pool: apply_async 2
Pool: apply_async 0 end
Pool: apply_async 1 end
Pool: apply_async 3
Pool: apply_async 2 end
Pool: apply_async 3 end
Main end
6.057688236236572


----------------------------
演示 进程池 - apply_async异步中的 回调函数,体会异步的过程


总结:
我们看到: 
callback 3321 apply_async 0funcCallback
mian pro 3321
这两个id号码是相同的,而且我们知道 mian pro 3321 一定是主进程,所以
callback 3321 apply_async 0funcCallback 也一定是运行在主进程中。
那么问题来了,主进程,我们写的是死循环:


    while True:
        time.sleep(2)
        print('mian pro',os.getpid())
应该一直运行才对啊?!中间怎么会被打断去做了其他事情呢:
callback 3321 apply_async 0funcCallback
实际这就是异步的一个实例,当子进程去做睡眠的时候:
def func(str):
    print ("Pool:", str,os.getpid())
    time.sleep(3)
他们告诉主进程,“我们在睡觉,用不到时间片,你拿去用吧”,
于是主进程被通知,快去用时间片执行回调吧!于是正在        
print('mian pro',os.getpid())  (写作业的我)被打断了,去做另外一件事情
callback 3321 apply_async 2funcCallback
callback 3321 apply_async 1funcCallback
callback 3321 apply_async 0funcCallback
(去拿书),这就叫异步。


注意:
异步会造成某个进程的死循环任务被打破,去做另外一件事情。


from multiprocessing import Pool
import time
import os


def func(str):
    print ("Pool:", str,os.getpid())
    time.sleep(3)
    print ("Pool:", str, os.getpid(),"end")
    return str+'funcCallback'


def cbFunc(args):
    print('callback',os.getpid(),args)


if __name__ == "__main__":
    pool = Pool(processes = 3)
 
    for i in range(4):
        msg = "apply_async %d" % (i)
        pool.apply_async(func, (msg, ),callback=cbFunc)   


    while True:
        time.sleep(2)
        print('mian pro',os.getpid())


tarena@tedu:~/aid1709/thread_1104_1108$ python3 thread_1108.py 
Pool: apply_async 0 3322
Pool: apply_async 1 3323
Pool: apply_async 2 3324
mian pro 3321
Pool: apply_async 2 3324 end
Pool: apply_async 0 3322 end
Pool: apply_async 3 3324
Pool: apply_async 1 3323 end
callback 3321 apply_async 2funcCallback
callback 3321 apply_async 1funcCallback
callback 3321 apply_async 0funcCallback
mian pro 3321
Pool: apply_async 3 3324 end
callback 3321 apply_async 3funcCallback
mian pro 3321
mian pro 3321
mian pro 3321
mian pro 3321
mian pro 3321










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


作业:




1.将共享内存中的数组Array中的元素值改为 0,1,2,3,4,5,7,8,9
2.将进程池apply.py中多余的任务是哪个进程做的 id 打印出来
3.将今天的进程池demo运行出来




第1题:
#演示共享内存-为数组赋值
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
    L = [0,1,2,3,4,5,6,7,8,9]
    a = multiprocessing.Array('i',L)  
    p = multiprocessing.Process(target = trans,args = (a,num))
    
    p.start()


执行结果:
tarena@tedu:~/aid1709/thread$ python3 进程池apply.py 
Pool: apply 0
当前的子进程的id是:18587
Pool: apply 0 end 


Pool: apply 1
当前的子进程的id是:18588
Pool: apply 1 end 


Pool: apply 2
当前的子进程的id是:18589
Pool: apply 2 end 


Pool: apply 3
当前的子进程的id是:18587
Pool: apply 3 end 


Main end
12.115739822387695


--------------------------------


第2题:
from multiprocessing import Pool
import time
import os


def func(str):
    print ("Pool:", str)
    print('当前的子进程的id是:%d' % (os.getpid()))
    time.sleep(3)
    print ("Pool:", str, "end",'\n')


if __name__ == "__main__":
    p = Pool(processes = 3)
    time1 = time.time()# 进程池中有3个进程,但是有4个任务,
    for i in range(4):
        
        msg = "apply %d" %(i)
        p.apply(func, (msg, ))  
 
    
    p.close()# close 必须在join之前
    p.join()# join阻塞等待
    print ("Main end")
    print(time.time() - time1)


执行结果:
tarena@tedu:~/aid1709/thread$ python3 进程池apply.py 
Pool: apply 0
当前的子进程的id是:18587
Pool: apply 0 end 


Pool: apply 1
当前的子进程的id是:18588
Pool: apply 1 end 


Pool: apply 2
当前的子进程的id是:18589
Pool: apply 2 end 


Pool: apply 3
当前的子进程的id是:18587
Pool: apply 3 end 


Main end

12.115739822387695


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

相关代码:



演示 信号量

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-2get
Process-2release
main end
Process-1get
Process-1release
Process-4get
Process-5get
Process-5release
Process-4release
Process-3get
Process-3release


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


演示事件


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())) #当且仅当内部标志为真时返回true




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/thread114_1108/day3$ python3 shiyan.py 
wait for event:starting
wait for timeout:starting
wait for event timeout is_set:False
main event is set
wait for event is_set:True




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


演示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'))






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


演示共享内存-为数组赋值


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
    L = [0,1,2,3,4,5,6,7,8,9]
    a = multiprocessing.Array('i',L)  #数组的类型 int 数组的长度是10,默认的元素为0
    p = multiprocessing.Process(target = trans,args = (a,num))#创建进程 将共享数组和长度传递给进程
    
    p.start()


tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
test share memory
0
1
2
3
4
5
6
7
8
9
消耗了0:00:00.000206


-------------------------------


演示共享内存-为数组赋值


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()


tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
test share memory
0
0
0
0
0
0
0
0
0
0
消耗了0:00:00.000449




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


演示 进程池 


from multiprocessing import Pool
import time


def Cal(n):
    sum = 0
    for i in range(n):
        sum += i*i
    return sum


if __name__ == '__main__':


    calCount = 10000  #计算到calCount-1 平方和
    check = 1001  #验证加到此时的平方和


    t1 = time.time()   #用进程池算平方和
    p = Pool()
    result = p.map(Cal,range(calCount))  #计算到0 到9999的平方和
    p.close()
    p.join()#进程池一定要有join方法,等子进程们结束再结束
    
    print(result[check])
    print('进程池花费时间:%f' % (time.time() - t1))






    t2 = time.time() #用单个进程做平方和,查看计算的时间
    result2 =[]
    for x in range(calCount):
        result2.append(Cal(x))
    print(result2[check])
    print('进程池花费时间:%f' % (time.time() - t2))


tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
333833500
进程池花费时间:2.145854
333833500
进程池花费时间:3.801389




-------------------------------


演示 进程池 - apply同步运行


from multiprocessing import Pool
import time
import os


def func(str):
    print ("Pool:", str)
    print('当前的子进程的id是:%d' % (os.getpid()))
    time.sleep(3)
    print ("Pool:", str, "end",'\n')


if __name__ == "__main__":
    p = Pool(processes = 3)
    time1 = time.time()# 进程池中有3个进程,但是有4个任务,
    for i in range(4):
        
        msg = "apply %d" %(i)
        p.apply(func, (msg, ))  
 
    
    p.close()# close 必须在join之前
    p.join()# join阻塞等待
    print ("Main end")
    print(time.time() - time1)


tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
Pool: apply 0
当前的子进程的id是:20070
Pool: apply 0 end 


Pool: apply 1
当前的子进程的id是:20069
Pool: apply 1 end 


Pool: apply 2
当前的子进程的id是:20071
Pool: apply 2 end 


Pool: apply 3
当前的子进程的id是:20070
Pool: apply 3 end 


Main end
12.116149425506592




-------------------------------


演示 进程池 - apply_async异步运行


from multiprocessing import Pool
import time


def func(str):
    print ("Pool:", str)
    time.sleep(3)
    print ("Pool:", str, "end")


if __name__ == "__main__":
    pool = Pool(processes = 3)
    time1 = time.time();
    for i in range(4):
        msg = "apply_async %d" % (i)
        pool.apply_async(func, (msg, ))   


    #print ("for end")


    pool.close()# close 必须在join之前
    pool.join()# join阻塞等待 
    print ("Main end")
    print(time.time() - time1)




tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
Pool: apply_async 0
Pool: apply_async 1
Pool: apply_async 2
Pool: apply_async 0 end
Pool: apply_async 1 end
Pool: apply_async 3
Pool: apply_async 2 end
Pool: apply_async 3 end
Main end
6.057688236236572




 import multiprocessing


class Channel(object):
    def __init__(self,maxsize):
        self.buffer = multiprocessing.Array('d',maxsize)    #双精度 浮点值
        self.buffer_index = multiprocessing.value('i')
        self.buffer.value = 0
        self.current_consumer_index = 0
        self.empty = multiprocessing.Semaphore(1)


    def send(self,value):
    def recv(self):


def consumer(ch,count):




def consumer(count,ch):




__name__ == '__mian__':
    ch == Channel(100)
    p =multiprocessing.Process(target=cosumer,args=(ch,50))


    p.start()
    producer(50,ch)
    p.join()


    print('DONE')


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


演示 信号量


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-2get
Process-2release
main end
Process-1get
Process-1release
Process-4get
Process-5get
Process-5release
Process-4release
Process-3get
Process-3release


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


演示事件


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())) #当且仅当内部标志为真时返回true




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/thread114_1108/day3$ python3 shiyan.py 
wait for event:starting
wait for timeout:starting
wait for event timeout is_set:False
main event is set
wait for event is_set:True




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


演示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'))






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


演示共享内存-为数组赋值


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
    L = [0,1,2,3,4,5,6,7,8,9]
    a = multiprocessing.Array('i',L)  #数组的类型 int 数组的长度是10,默认的元素为0
    p = multiprocessing.Process(target = trans,args = (a,num))#创建进程 将共享数组和长度传递给进程
    
    p.start()


tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
test share memory
0
1
2
3
4
5
6
7
8
9
消耗了0:00:00.000206


-------------------------------


演示共享内存-为数组赋值


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()


tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
test share memory
0
0
0
0
0
0
0
0
0
0
消耗了0:00:00.000449




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


演示 进程池 


from multiprocessing import Pool
import time


def Cal(n):
    sum = 0
    for i in range(n):
        sum += i*i
    return sum


if __name__ == '__main__':


    calCount = 10000  #计算到calCount-1 平方和
    check = 1001  #验证加到此时的平方和


    t1 = time.time()   #用进程池算平方和
    p = Pool()
    result = p.map(Cal,range(calCount))  #计算到0 到9999的平方和
    p.close()
    p.join()#进程池一定要有join方法,等子进程们结束再结束
    
    print(result[check])
    print('进程池花费时间:%f' % (time.time() - t1))






    t2 = time.time() #用单个进程做平方和,查看计算的时间
    result2 =[]
    for x in range(calCount):
        result2.append(Cal(x))
    print(result2[check])
    print('进程池花费时间:%f' % (time.time() - t2))


tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
333833500
进程池花费时间:2.145854
333833500
进程池花费时间:3.801389




-------------------------------


演示 进程池 - apply同步运行


from multiprocessing import Pool
import time
import os


def func(str):
    print ("Pool:", str)
    print('当前的子进程的id是:%d' % (os.getpid()))
    time.sleep(3)
    print ("Pool:", str, "end",'\n')


if __name__ == "__main__":
    p = Pool(processes = 3)
    time1 = time.time()# 进程池中有3个进程,但是有4个任务,
    for i in range(4):
        
        msg = "apply %d" %(i)
        p.apply(func, (msg, ))  
 
    
    p.close()# close 必须在join之前
    p.join()# join阻塞等待
    print ("Main end")
    print(time.time() - time1)


tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
Pool: apply 0
当前的子进程的id是:20070
Pool: apply 0 end 


Pool: apply 1
当前的子进程的id是:20069
Pool: apply 1 end 


Pool: apply 2
当前的子进程的id是:20071
Pool: apply 2 end 


Pool: apply 3
当前的子进程的id是:20070
Pool: apply 3 end 


Main end
12.116149425506592




-------------------------------


演示 进程池 - apply_async异步运行


from multiprocessing import Pool
import time


def func(str):
    print ("Pool:", str)
    time.sleep(3)
    print ("Pool:", str, "end")


if __name__ == "__main__":
    pool = Pool(processes = 3)
    time1 = time.time();
    for i in range(4):
        msg = "apply_async %d" % (i)
        pool.apply_async(func, (msg, ))   


    #print ("for end")


    pool.close()# close 必须在join之前
    pool.join()# join阻塞等待 
    print ("Main end")
    print(time.time() - time1)




tarena@tedu:~/aid1709/thread114_1108/day3$ python3 shiyan.py 
Pool: apply_async 0
Pool: apply_async 1
Pool: apply_async 2
Pool: apply_async 0 end
Pool: apply_async 1 end
Pool: apply_async 3
Pool: apply_async 2 end
Pool: apply_async 3 end
Main end
6.057688236236572




















































你可能感兴趣的:(python中的线程与进程认知)