python在windows和linux环境的进程对比及进程和进程之间的通信

1.fork进程:
(1)在windows系统中不可以用fork来创建进程,linux可以,但是创建大量进程使用很不方便。

2.Process进程:

 1 #多任务,进程
 2 from multiprocessing import Process
 3 import time
 4 def test():
 5     while True:
 6         print("-------test------")
 7         time.sleep(1)
 8 def test1():
 9     while True:
10         print('------test2')
11         time.sleep(2)
12 
13 def main():
14     p1= Process(target=test) #开启一个进程
15     p1.start()#让这个进程开始执行test函数里面的代码
16     p2=Process(target=test1)
17     p2.start()
18     p1.join() #等待 就是join会让子进程进行完(完成),才会执行主进程(join还可以带参数 等待多长时间)
19     print('---主进程----')
20 if __name__ == '__main__':
21     main()

windows下运行结果:

 1 -------test------
 2 ------test2
 3 -------test------
 4 -------test------
 5 ------test2
 6 -------test------
 7 -------test------
 8 ------test2
 9 -------test------
10 -------test------
11 ------test2
12 -------test------

说明:

(1)if __name__ == '__main__':
在windows环境下创建进程及相关的可执行代码必须放在if __name__ == '__main__':下,否则会报错;但是linux系统没有这个问题。

 三:进程池Pool

     当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程,但如果是成百上千个目标时,手动的去创建进程的工作量巨大,此时就可以用到multiprocessing模块中提供的Pool .

     初始化Pool时,可以指定一个最大的进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行。 1 from multiprocessing import Pool

 2 def worker():
 3     print('-----这里是要执行的任务')
 4 def test():
 5     po = Pool(3)  # 在这里创建线程池,3 是代表这个线程池中线程最大数量是3
 6     po.apply_async(worker())  # 向线程中添加任务,(就是开辟线程)(apply_async()是非堵塞的方式){po.apply(worker)这个是堵塞的方式}
7 po.close() #关闭线程池,相当于不在添加新任务了 8 po.join() #等待所有的子进程执行完成,必须放在close之后(主进程创建/添加任务后,主进程 默认不会等待进程池中的任务完成后才结束,而是 当主进程做完任务后 立刻结束,,,如果这个地方没有join,会导致进程池中的任务不会执行) 9 10 if __name__ =='__main__': 11 test()

运行结果:

1 -----这里是要执行的任务

(1)Pool进程也一样,在windows环境下相关的可执行代码必须放置在if __name__ == '__main__'下。

 四:进程间通信:Queue

        proccess之间有时需要通信,操作系统提供了很多机制来实现进程间的通信。

可以使用multiprocessing模块中的Queue实现多进程之间的数据传递,Queue本身就是一个消息列队程序

 1 >>> q = Queue(3)# 初始化一个Queue对象,最大可接收三条put消息
 2 >>> q.qsize() #返回当前队列包含的消息数量
 3 0
 4 >>> q.put('第一条消息')#向当前队列添加数据
 5 >>> q.qsize()
 6 1
 7 >>> q.put('第二条消息')
 8 >>> q.put('第三条消息')
 9 >>> q.qsize()
10 3
11 >>> q.get()# 从队列里取出数据,(先进先出)
12 '第一条消息'
13 >>> q.qsize()
14 2
15 >>> q.get()
16 '第二条消息'
17 >>> q.qsize()
18 1
19 >>> q.get()
20 '第三条消息'
21 >>> q.qsize()
22 0
23 >>> q.empty()#判断当前队列是否为空,为空则返回True,否则返回False
24 True
25 >>> q.full()#判断当前队列是否是满的,满的则返回True,否则返回False
26 False
27 >>> q.put('再添加一条消息')
28 >>> q.get() #get()从队列里取数据如果有数据就会直接取出来,否则会一直等待
29 '再添加一条消息'
30 >>> q.get_nowait()#从队列里取数据如果没有数据则不以等待,直接会以异常提示
31 Traceback (most recent call last):
32   File "<pyshell#33>", line 1, in <module>
33     q.get_nowait()#从队列里取数据如果没有数据则不以等待,直接会以异常提示
34   File "E:\python\lib\multiprocessing\queues.py", line 126, in get_nowait
35     return self.get(False)
36   File "E:\python\lib\multiprocessing\queues.py", line 107, in get
37     raise Empty
38 queue.Empty
39 >>>  

Process创建进程之间的通信

 示例代码:

 1 #进程间的通信,Process版的
 2 from multiprocessing import Queue
 3 from multiprocessing import Process
 4 def writer(a):
 5         print('向队列中添加数据')
 6         x = a.put('写入的数据')
 7 def read(b):
 8     print('读取队列中的数据')
 9     if b.empty()== False:
10         y =b.get()
11         print(y)
12     else:
13         print('没有数据')
14 if __name__ == '__main__':
15     q = Queue()  # 使用Queue()来初始化
16     p1= Process(target=writer,args=(q,))
17     p2=Process(target=read,args=(q,))
18     p1.start()
19     p2.start()

运行结果:

1 向队列中添加数据
2 读取队列中的数据
3 写入的数据

Pool进程池创建进程之间的通信

注意:Pool进程池创建的进程之间通信,需要导入Manager

示例代码:

 1 #进程间的通信 Pool
 2 from multiprocessing import Manager
 3 from multiprocessing import Pool
 4 def writer(a):
 5         print('向队列中添加数据')
 6         a.put('写入的数据')
 7 def read(b):
 8     print('读取队列中的数据')
 9     if b.empty()== False:
10         y =b.get()
11         print(y)
12     else:
13         print('没有数据')
14 def test():
15     q =Manager().Queue()  # 使用Manager中的Queue()来初始化
16     p=Pool(3)
17     p.apply_async(writer,(q,))
18     p.apply_async(read,(q,))
19     p.close()
20     p.join()
21 if __name__ =='__main__':
22     test()

运行结果:

1 向队列中添加数据
2 读取队列中的数据
3 写入的数据

一个多进程和进程通信的实例代码:

 实现多进程拷贝文件夹

 1 import os
 2 from multiprocessing import Manager,Pool
 3 import time
 4 
 5 def copyFileTask(name,oldFolderName,newFolderName,qu):
 6     '拷贝文件操作'
 7     fr = open(oldFolderName+'/'+name,'r',encoding='utf-8')
 8     content = fr.read(1024)
 9     fw = open(newFolderName+'/'+name,'w',encoding='utf-8')
10     fw.write(content)
11     fr.close()
12     fw.close()
13     qu.put(name)
14 
15 def main():
16     startTime=time.time()
17     oldFolderName = input("请输入你要拷贝的文件夹名称:") #获取要拷贝的文件夹名称
18     #读取文件夹中所有的文件名
19     listNames =  os.listdir(oldFolderName)
20     #创建一个新的文件夹
21     newFolderName = oldFolderName+'复件'
22     os.mkdir(newFolderName)
23     #创建进程池,实现多任务
24     po = Pool(5)
25     qu=Manager().Queue()
26     #遍历listNames,获取每一个文件的名称
27     for name in listNames:
28         po.apply_async(copyFileTask,args=(name,oldFolderName,newFolderName,qu))
29 
30     num = 0
31     allNum= len(listNames)
32     while num < allNum:
33         qu.get()
34         print()
35         num += 1
36         copyRote= num/allNum # 求出拷贝的进度条
37         print('\copy的进度是:%.2f%%'%(copyRote*100),end='')
38         print('')
39         overTime=time.time()
40         allTime=overTime - startTime
41         print(allTime)
42 if __name__ == '__main__':
43     main()

运行结果:

 1 请输入你要拷贝的文件夹名称:aaaa
 2 
 3 \copy的进度是:4.35%
 4 3.575204372406006
 5 
 6 \copy的进度是:8.70%
 7 3.575204372406006
 8 
 9 \copy的进度是:13.04%
10 3.579204559326172
11 
12 \copy的进度是:17.39%
13 3.580204725265503
14 
15 \copy的进度是:21.74%
16 3.581204652786255
17 
18 \copy的进度是:26.09%
19 3.585205078125
20 
21 \copy的进度是:30.43%
22 3.585205078125
23 
24 \copy的进度是:34.78%
25 3.588205099105835
26 
27 \copy的进度是:39.13%
28 3.588205099105835
29 
30 \copy的进度是:43.48%
31 3.589205265045166
32 
33 \copy的进度是:47.83%
34 3.593205451965332
35 
36 \copy的进度是:52.17%
37 3.595205307006836
38 
39 \copy的进度是:56.52%
40 3.595205307006836
41 
42 \copy的进度是:60.87%
43 3.596205472946167
44 
45 \copy的进度是:65.22%
46 3.600205898284912
47 
48 \copy的进度是:69.57%
49 3.601206064224243
50 
51 \copy的进度是:73.91%
52 3.602205991744995
53 
54 \copy的进度是:78.26%
55 3.603205919265747
56 
57 \copy的进度是:82.61%
58 3.60520601272583
59 
60 \copy的进度是:86.96%
61 3.609206199645996
62 
63 \copy的进度是:91.30%
64 3.610206365585327
65 
66 \copy的进度是:95.65%
67 3.6122066974639893
68 
69 \copy的进度是:100.00%
70 3.613206624984741

 

posted @ 2018-03-24 00:23  奋斗的小虫子  阅读(1131)  评论(0编辑  收藏  举报