设为首页 加入收藏

TOP

Python并发之多进程(一)
2018-10-19 16:45:53 】 浏览:44
Tags:Python 并发 进程

一,进程的理论基础

  一个应用程序,归根结底是一堆代码,是静态的,而进程才是执行中的程序,在一个程序运行的时候会有多个进程并发执行。

  进程和线程的区别:

  •     进程是系统资源分配的基本单位。
  •     一个进程内可以包含多个线程,属于一对多的关系,进程内的资源,被其内的线程共享
  •     线程是进程运行的最小单位,如果说进程是完成一个功能,那么其线程就是完成这个功能的基本单位
  •     进程间资源不共享,多进程切换资源开销,难度大,同一进程内的线程资源共享,多线程切换资源开销,难度小

  进程与线程的共同点:

    都是为了提高程序运行效率,都有执行的优先权

 

二,Python的多进程( multiprocessing模块)

创建一个进程(和创建线程类似)

方法一:创建Process对象,通过对象调用start()方法启动进程

from multiprocessing import Process

def foo(name):
    print('hello,%s'%name)

if __name__ == '__main__':
    p1=Process(target=foo,args=('world',))
    p2 = Process(target=foo, args=('China',))
    p1.start()
    p2.start()
    print('=====主进程=====')
    
    # == == =主进程 == == =
    # hello, world
    # hello, China
    #主进程和子进程并发执行  

 注意:Process对象只能在在 if __name__ == '__main__':下创建,不然会报错。

方法二:自定义一个类继承Process类,并重写run()方法,将执行代码放在其内

from multiprocessing import Process

class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        print('hello,%s'%self.name)

if __name__ == '__main__':
    myprocess1 = MyProcess('world')
    myprocess2 = MyProcess('world')
    myprocess1.start()
    myprocess2.start()

 

 

 Process内置方法

实例方法:
p.start():启动进程,并调用该子进程中的p.run() 

p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法  

p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁

p.is_alive():如果p仍然运行,返回True

p.join([timeout]):主线程等待p终止。timeout是可选的超时时间

 

Process属性

p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置

p.name:进程的名称

p.pid:进程的pid

p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可) 

守护进程

类似于守护线程,只不过守护线程是对象的一个方法,而守护进程封装成对象的属性。

from multiprocessing import Process
import time
class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        time.sleep(3)
        print('hello,%s'%self.name)

if __name__ == '__main__':
    myprocess1=MyProcess('world')
    myprocess1.daemon = True
    myprocess1.start()
    print('结束')

#不会输出‘hello world’,因为设置为守护进程,主进程不会等待

 

也可以使用join方法,使主进程等待

from multiprocessing import Process
import time
class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        time.sleep(3)
        print('hello,%s'%self.name)

if __name__ == '__main__':
    myprocess1=MyProcess('world')
    myprocess1.daemon = True
    myprocess1.start()
    myprocess1.join()  #程序阻塞
    print('结束')
join()

 

进程同步和锁

  进程虽然不像线程共享资源,但是这并不意味着进程间不需要加锁,比如不同进程会共享同一个终端屏幕),或者操作同一个文件,数据库,那么数据安全还是很有必要的,因此我们可以加锁,

from multiprocessing import Process,Lock
import time
def a_print(l): #需要传入对象,因为信息不共享
    l.acquire()
    print('我要打印信息')
    time.sleep(1)
    print('我打印完了')
    l.release()

if __name__ == '__main__':
    l = Lock()
    for i in range(20):
        p = Process(target=a_print,args=(l,))
        p.start()

 

信号量(Semaphore)

能够并发执行的进程数,超出的进程阻塞,直到有进程运行完成。

  Semaphore管理一个内置的计数器,
  每当调用acquire()时内置计数器-1;
  调用release() 时内置计数器+1;
  计数器不能小于0;当计数器为0时,acquire()将阻塞进程直到其他进程调用release()。

from multiprocessing import Process,Queue,Semaphore
import time,random

def seat(s,n):
    s.acquire()
    print('学生%d坐下了'%n)
    time.sleep(random.randint(1,2))
    s.release()

if __name__ == '__main__':
    s = Semaphore(5)
    for i in range(20):
        p = Process(target=seat,ar
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Python开发【第四篇】函数 下一篇Python算法基础

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目