zoukankan      html  css  js  c++  java
  • Python之多线程和多进程

       

    一、多线程

    1、顺序执行单个线程,注意要顺序执行的话,需要用join。

     1 #coding=utf-8
     2 
     3 from threading import Thread
     4 import time
     5 
     6 def my_counter():
     7     i = 0
     8     for _ in range(100000000):
     9         i = i + 1
    10     return True
    11 
    12 def main():
    13     thread_array = {}
    14     start_time = time.time()
    15     for tid in range(2):
    16         t = Thread(target=my_counter)
    17         t.start()
    18         # join阻塞下个线程,除非当前线程执行完毕
    19         t.join()
    20     end_time = time.time()
    21     print("Total time: {}".format(end_time - start_time))
    22 
    23 if __name__ == '__main__':

     执行结果: 

    2、同时执行两个并发线程

     1 #coding=utf-8
     2 
     3 from threading import Thread
     4 import time
     5 
     6 def prn_obj(obj):
     7     return '
    '.join(['%s:%s' % item for item in obj.__dict__.items()])
     8 
     9 def my_counter():
    10     i = 0
    11     for _ in range(100000000):
    12         i = i + 1
    13     return True
    14 
    15 def main():
    16     thread_array = {}
    17     start_time = time.time()
    18     for tid in range(2):
    19         t = Thread(target=my_counter)
    20         t.start()
    21         thread_array[tid] = t
    22     for i in range(2):
    23         thread_array[i].join()
    24         # print("thread type: {}".format(prn_obj(thread_array[i])))
    25         print("thread type: {}".format(thread_array[i].name))
    26     end_time = time.time()
    27     print("Total time: {}".format(end_time - start_time))
    28 
    29 if __name__ == '__main__':
    30     main()

    下面是用了打印所有属性的方法,这个方法代码中注释了,可重复利用的代码块

    二、多进程

    1、multiprocessing

    multiprocessing是跨平台版本的多进程模块,它提供了一个Process类来代表一个进程对象,下面是示例嗲吗

    import os
    if __name__=='__main__': 
        print 'Process (%s) start...' % os.getpid()
        pid = os.fork()
        print pid
        if pid==0:
                print 'I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid())
        else:
                print 'I (%s) just created a child process (%s).' % (os.getpid(), pid)

    这个程序如果用单进程写则需要执行10秒以上的时间,而用多进程则启动10个进程并行执行,只需要用1秒多的时间。

    在python中建议使用多进程而不是多线程,因为在python的多线程中有个全局解释器锁,这样在做并发效率会不是很高。

    进程和进程直接可以用不同的全局解释器锁,可以提高程序效率。

    2、进程间通信Queue

    进程和进程之前是独立的,如果需要通信就需要Queue创建的对象来处理

     1 from multiprocessing import Process,Queue
     2 import time
     3 
     4 def write(q):
     5     for i in ['A','B','C','D','E']:
     6         print('Put %s to queue' % i)
     7         q.put(i)
     8         time.sleep(0.5)
     9 
    10 def read(q):
    11     while True:
    12         v = q.get(True)
    13         print('get %s form queue' %v)
    14 
    15 if __name__ == '__main__':
    16     q = Queue()
    17     pw = Process(target=write,args=(q,))
    18     pr = Process(target=read,args=(q,))
    19     pw.start()
    20     pr.start()
    21     pr.join()
    22     pr.terminate()

    3、进程池Pool

     1 #coding=utf-8
     2 
     3 from multiprocessing import Pool
     4 import time
     5 
     6 def f(x):
     7     print x*x
     8     time.sleep(2)
     9     return x*x
    10 
    11 if __name__ == '__main__':
    12     '''定义启动的进程数量'''
    13     pool = Pool(processes=5)
    14     res_list = []
    15 
    16     for i in range(10):
    17         '''
    18         以异步并行的方式启动进程,如果要同步等待的方式,
    19         可以在每次启动进程之后调用res.get()方法
    20         也可以使用Pool.appley
    21         '''
    22         res = pool.apply_async(f,[i,])
    23         print('--------:',i)
    24         res_list.append(res)
    25     pool.close()
    26     pool.join()
    27     for r in res_list:
    28         print "result",(r.get(timeout=5))

     三、多线程与多进程的对比

    在一般情况下多个进程的内存资源是相互独立的,而多线程可以共享同一个进程中的内存资源

     1 #coding=utf-8
     2 
     3 from multiprocessing import Process
     4 import threading
     5 import time
     6 lock = threading.Lock()
     7 
     8 def run(info_list,n):
     9     lock.acquire()
    10     info_list.append(n)
    11     lock.release()
    12     print('%s' % info_list)
    13 
    14 if __name__ == '__main__':
    15     info = []
    16     for i in range(10):
    17         # target为子进程执行的函数,args为需要给函数传递的参数
    18         p = Process(target=run,args=[info,i])
    19         p.start()
    20         p.join()
    21     time.sleep(1)#这里为了输出整齐让主进程的执行等一下子进程
    22     print('-------------------threading---------------------')
    23     for i in xrange(1,10):
    24         p = threading.Thread(target=run,args=[info,i])
    25         p.start()
    26         p.join()

  • 相关阅读:
    linux(centos6.9) 安装mongoDB
    vue $refs
    vue $emit的使用方式
    docker上部署一个项目常用命令
    Nginx之Location匹配规则
    Github Packages和Github Actions实践之CI/CD
    消息中间件选型分析:从 Kafka 与 RabbitMQ 的对比看全局
    发布Jar包到maven中央仓库
    一些小Tip
    有风格的程序员,写有风格的代码
  • 原文地址:https://www.cnblogs.com/goodboy-heyang/p/7073355.html
Copyright © 2011-2022 走看看