zoukankan      html  css  js  c++  java
  • 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:pythonlibmultiprocessingqueues.py", line 126, in get_nowait
    35     return self.get(False)
    36   File "E:pythonlibmultiprocessingqueues.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

  • 相关阅读:
    获取系统DPI、系统显示比例等
    [LeetCode] 698. Partition to K Equal Sum Subsets
    .NET Framework基础知识(二)(转载)
    linux week3
    多进程
    Python 析构方法__del__
    面向对象作业
    网页视频加速播放
    javaScript(5)---运算符
    javaScript(5)---运算符
  • 原文地址:https://www.cnblogs.com/qigege1104/p/8635618.html
Copyright © 2011-2022 走看看