• 【python】多进程、多线程、序列


    一、多进程

    1.子进程永远返回0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。

    2.multiprocessing

    multiprocessing模块提供了一个Process类来代表一个进程对象,下面的例子演示了启动一个子进程并等待其结束

     1 import os,time,random
     2 from multiprocessing import Process
     3 #运行多个子进程
     4 def run_child_process(name):
     5     print("run child process %s(%s)"%(name,os.getpid()))
     6 
     7 if __name__=='__main__':
     8     print("parent process %s"%os.getpid())
     9     p1=Process(target=run_child_process,args=("p1",))
    10     p1.start()
    11     p1.join()
    12     print("child process end")

    3.进程池 pool

    如果要启动大量的子进程,可以用进程池的方式批量创建子进程:

     1 from multiprocessing import Pool
     2 import os,time,random
     3 def long_time_task(name):
     4     print("run task %s(%s)"%(name,os.getpid()))
     5     start=time.time()
     6     time.sleep(random.random()*3)
     7     end=time.time()
     8     print("task %s takes %0.2f seconds"%(name,(end-start)))
     9 
    10 if __name__=='__main__':
    11     print("parent process %s"%os.getpid())
    12     p=Pool(4)
    #pool的默认值是cpu数
    13 for i in range(5): 14 p.apply_async(long_time_task,args=(i,)) 15 print("waiting for all subprocess done") 16 p.close() 17 p.join() 18 print("all subprocess done")

    执行结果:

    Parent process 4984.
    Waiting for all subprocesses done...
    Run task 3 (9496)...
    Task 3 runs 1.65 seconds.
    Run task 4 (9496)...
    Task 4 runs 0.16 seconds.
    Run task 0 (11036)...
    Task 0 runs 2.25 seconds.
    Run task 2 (8680)...
    Task 2 runs 2.67 seconds.
    Run task 1 (11100)...
    Task 1 runs 2.97 seconds.
    All subprocesses done.
    [Finished in 3.7s]

    二、多线程

    多任务可以由多进程完成,也可以由一个进程内的多线程完成。

    我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程

    1.启动线程

     1 import threading,time
     2 def loop():
     3     print("thread %s is running..."%threading.current_thread().name)
     4     n=0
     5     while n<5:
     6         n=n+1
     7         print("thread %s>>>%s"%(threading.current_thread().name,n))
     8         time.sleep(1)
     9     print("thread %s is ended"%threading.current_thread().name)
    10 print("thread %s is running"%threading.current_thread().name)
    11 t=threading.Thread(target=loop,name="loopthread")
    12 t.start()  
    13 t.join()
    14 print("thread %s is ended"%threading.current_thread().name)

    执行结果:

     1 thread MainThread is running
     2 thread loopthread is running...
     3 thread loopthread>>>1
     4 thread loopthread>>>2
     5 thread loopthread>>>3
     6 thread loopthread>>>4
     7 thread loopthread>>>5
     8 thread loopthread is ended
     9 thread MainThread is ended
    10 [Finished in 5.3s]

    2.lock

    多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了

     1 import time,threading
     2 balance=0
     3 lock=threading.Lock()
     4 def change_it(n):
     5     global balance
     6     balance=balance+n
     7     balance=balance-n
     8 
     9 def run_thread(n):
    10     for i in range(100000):
    11         lock.acquire()
    12         try:
    13             change_it(n)
    14         finally:
    15             lock.release()
    16 t1=threading.Thread(target=run_thread,args=(5,))
    17 t2=threading.Thread(target=run_thread,args=(8,))
    18 t1.start()
    19 t2.start()
    20 t1.join()
    21 t1.join()
    22 print(balance)

    三、队列

    1.Process之间肯定是需要通信的,操作系统提供了很多机制来实现进程间的通信。Python的multiprocessing模块包装了底层的机制,提供了QueuePipes等多种方式来交换数据。

    我们以Queue为例,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据:

     1 from multiprocessing import Process, Queue
     2 import os, time, random
     3 # 写数据进程执行的代码:
     4 def write(q):
     5     print('Process to write: %s' % os.getpid())
     6     for value in ['A', 'B', 'C']:
     7         print('Put %s to queue...' % value)
     8         q.put(value)
     9     time.sleep(random.random())
    10 
    11 # 读数据进程执行的代码:
    12 def read(q):
    13     print('Process to read: %s' % os.getpid())
    14     while True:
    15         value = q.get(True)
    16         print('Get %s from queue.' % value)
    17 
    18 if __name__=='__main__':
    19     # 父进程创建Queue,并传给各个子进程:
    20     q = Queue()
    21     pw = Process(target=write, args=(q,))
    22     pr = Process(target=read, args=(q,))
    23     # 启动子进程pw,写入:
    24     pw.start()
    25     # 启动子进程pr,读取:
    26     pr.start()
    27     # 等待pw结束:
    28     pw.join()
    29     # pr进程里是死循环,无法等待其结束,只能强行终止:
    30     pr.terminate()

    原文地址:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431927781401bb47ccf187b24c3b955157bb12c5882d000

    https://yuedu.baidu.com/ebook/0f6a093b7dd184254b35eefdc8d376eeaeaa17e3?pn=1&rf=https%3A%2F%2Fyuedu.baidu.com%2Febook%2F0f6a093b7dd184254b35eefdc8d376eeaeaa17e3

  • 相关阅读:
    DRF 分页
    DRF 权限 频率
    DRF 版本 认证
    opencl(6)读写传输命令、内存映射命令
    opencl(5)缓存对象
    opencl(4)命令队列
    opencl(3)程序、内核
    opencl(2)平台、设备、上下文的获取与信息获取
    epoll
    unsigned 变量名:n
  • 原文地址:https://www.cnblogs.com/dhs94/p/9005336.html
Copyright © 2020-2023  润新知