多进程、多线程、序列

一、多进程

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

猜你喜欢

转载自www.cnblogs.com/dhs94/p/9005336.html