# 多进程# Windows下面没有fork ,请在linux下跑下面的代码import osprint('Process (%s) start...' % os.getpid())pid = os.fork()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))
# windows 下没有 fork,实现多进程要使用 multiprocessing 模块from multiprocessing import Processimport os, timedef run_proc(name): print('Run child process %s (%s)...' % (name, os.getpid()))if __name__=='__main__': print('Parent process %s.' % os.getpid()) p = Process(target=run_proc, args=('test',)) # target 将函数作为单个进程,args 是传参数 print('Child process will start.') p.start() # 启动 p.join() # 等待子进程结束后继续运行 print('Child process is end.') print('..................') time.sleep(1)# Pool# 要启动大量的子进程,可以用进程池的方式批量创建子进程:from multiprocessing import Poolimport os, time, randomdef long_time_task(name): print('Run task %s (%s)' % (name, os.getpid())) start = time.time() # 返回当前时间的时间戳 time.sleep(random.random() * 3) # random() 方法返回随机生成的一个实数,它在[0,1)范围内。 end = time.time() print('Task %s runs %0.2f seconds' % (name, (end-start)))if __name__ == '__main__': print('Parent process %s.'% os.getpid()) p = Pool(3) for i in range(4): p.apply_async(long_time_task, args=(i,)) print('waiting for all subprocesses done...') p.close() p.join() print('Done') print('..................') time.sleep(1)# 对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了。# 进程间通信# Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。# 参考链接:https://www.cnblogs.com/kaituorensheng/p/4445418.html#_label5from multiprocessing import Process, Queueimport os, time, random# 写数据进程执行的代码:def write(q): print('Process to write: %s' % os.getpid()) for value in ['a','b','c']: print('Put %s to queue...' % value) q.put(value) time.sleep(random.random())# 读def read(q): print('Process to read: %s' % os.getpid()) while True: value = q.get(True) print('Gets %s from queue.' % value)if __name__ == '__main__': # 父进程创建队列,传递给各个子进程 q = Queue() pw = Process(target=write, args=(q,)) pr = Process(target=read, args=(q,)) pw.start() pr.start() pw.join() pr.terminate() # pr进程里是死循环,无法等待其结束,只能强行终止: print('Done') print('..................') time.sleep(1)############################################################### 多线程'''多任务可以由多进程完成,也可以由一个进程内的多线程完成。我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程。由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。'''# Python的标准库中,绝大多数情况下,我们只需要使用threading这个高级模块。# 启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行:import time, threading# 新进程执行的代码:def loop(): print('thread %s is running ...' % threading.current_thread().name) n = 0 while n < 3: n = n + 1 print('thread %s >>> %s' % (threading.current_thread().name,n)) time.sleep(1) print('thread %s ended.' % threading.current_thread().name)print('thread %s is running ...' % threading.current_thread().name)t = threading.Thread(target=loop, name='LoopTread') # 子线程的名字在创建时指定,我们用LoopThread命名子线程。名字仅仅在打印时用来显示,完全没有其他意义t.start()t.join()print('thread %s ended.' % threading.current_thread().name)# 任何进程默认就会启动一个线程,我们把该线程称为主线程,主线程又可以启动新的线程# current_thread()函数,它永远返回当前线程的实例。# Lock# 多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,# 而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。# 假定这是你的银行存款:balance = 0def change_it(n): # 先存后取,结果应该为0: global balance # 告诉Python这个变量名不是局部的,而是 全局 的 ### balance = balance + n balance = balance - n ### 这两句语句在一个线程里应该是要连续执行才对def run_thread(n): for i in range(5000000): change_it(n)t1 = threading.Thread(target=run_thread,args=(5,))t2 = threading.Thread(target=run_thread,args=(8,))t1.start()t2.start()t1.join()t2.join()print(balance) # 由于线程的调度是由操作系统决定的,当t1、t2交替执行时,只要循环次数足够多,balance的结果就不一定是0了。print('Done.......................')# 为函数 change_it 添加一个锁# 当某个线程开始执行change_it()时,该线程因为获得了锁,因此其他线程不能同时执行change_it(),只能等待,直到锁被释放后,获得该锁以后才能执行。balance = 0lock = threading.Lock()def run_thread(n): for i in range(5000000): # p(信号量) lock.acquire() try: change_it(n) finally: # v(信号量) lock.release()print(balance)print('Done.......................')