11.python并发入门(part9 多线程模块multiprocessing基本用法)

一、回顾多继承的概念。

由于GIL(全局解释器锁)的存在,在python中无法实现真正的多线程(一个进程里的多个线程无法在cpu上并行执行),如果想充分的利用cpu的资源,在python中需要使用进程。

二、multiprocessing模块的简介。

multiprocessing是python中用来管理多进程的包,与threading用法非常类似,它主要使用multiprocessing.Process对象来创建一个进程对象,该进程可以运行在python的函数中。

该Process(进程)对象与Thread(线程)对象的用法基本相同,同样具有start,join,run之类的方法,此外,multiprocessing也具有event,Lock,Semaphore,Condition类,这些对象可以像多线程那样,通过参数传递给各个进程。

其用法与threading包中的同名类一致。所以,multiprocessing的很大一部份与threading使用同一套API,只不过换成了多进程。

三、多进程的调用方式。

方式1:

#!/usr/local/bin/python2.7

# -*- coding:utf-8 -*-

from multiprocessing import Process

import time

def func1(name):

print ‘hello %s,%s‘ %(name,time.ctime())

time.sleep(1)

if __name__ == ‘__main__‘:

pro_list = []

for i in range(3):

p = Process(target=func1,args=str(i))

pro_list.append(p)

p.start()

for i in pro_list:

i.join()

print "ending...."

方式2:(通过类的方式来创建多进程。)

#!/usr/local/bin/python2.7

# -*- coding:utf-8 -*-

from multiprocessing import Process

import time

class myprocess(Process):

def __init__(self):

super(myprocess, self).__init__()

def run(self):

print "hello,%s,%s" %(self.name,time.ctime())

time.sleep(1)

if __name__ == ‘__main__‘:

pro_list = []

for i in range(3):

p = myprocess()

p.start()

pro_list.append(p)

for p in pro_list:

p.join()

print "ending!"

下面还有一个扩展示例,可以瞬间让你明白,父进程与子进程之间的关系。

#!/usr/local/bin/python2.7

# -*- coding:utf-8 -*-

from multiprocessing import Process

import time

import os

def info(title):

print "title:%s" %(title)

print "parent process:%s", os.getppid() #获得父进程的进程号也就是ppid

print "process id: %s", os.getpid() #获得当前进程的pid号

def func1(name):

info("func1")

print "hello %s" %(name)

if __name__ == ‘__main__‘:

info("main process")

time.sleep(1)

print "------------------"

p = Process(target=info,args=(‘su‘,))

p.start()

p.join()

输出结果:

title:main process

parent process:%s 40833  #主进程的父进程是pycharm,所以这个是pycharm的进程号

process id: %s 42454  #我们运行的py程序的进程号

------------------

title:su

parent process:%s 42454   #在主进程中又开了个子进程,所以这个子进程的父进程就是我们运行py文件的主进程号

process id: %s 42455  #子进程自己的pid。

三、Process类的常用属性以及方法的介绍。

  1. Process类在实例化对象的时候,都需要哪些参数?

Process([group [, target [, name [, args [, kwargs]]]]])

group:这个参数应该是指定一个进程组,这个参数的功能暂时还没有实现,所以必须是None(默认就是None)

target:这个进程所要执行的函数或者方法。

name:指定进程名 (也可以用来获取进程名)

args/kwargs:要传到函数里的参数。

2.关于进程对象的一些常用方法。

is_alive(): 返回这个进程是否在运行状态。

join(timeout):阻塞父进程,一直到这个子进程终止。

start():开启这个进程,等待cpu调度。

terminate() 直接对这个进程发起一个SIGTERM信号,立刻终止这个进程。

3.进程类的一些常用属性。

deamon (注意!这是一个property特殊属性,本质上是个函数)daemon属性用来创建一个守护进程。 (这个守护进程是用于守护父进程的,当父进程退出,这个守护进程也会退出。)

name  获得进程名。

pid 获得进程号。

时间: 2024-10-07 05:06:32

11.python并发入门(part9 多线程模块multiprocessing基本用法)的相关文章

11.python并发入门(part2 threading模块的基本使用)

一.在使用python多线程之前,你需要知道的. python的多线程中,实现并发是没有问题的,但是!!是无法实现真正的并行的. 这是因为python内部有个GIL锁(全局解释器锁),这个锁限制了在同一时刻,同一个进程中,只能有一个线程被运行!!! 二.threading模块的基本使用方法. 可以使用它来创建线程.有两种方式来创建线程. 1.通过继承Thread类,重写它的run方法. 2.创建一个threading.Thread对象,在它的初始化函数__init__中将可调用对象作为参数传入.

11.python并发入门(part3 多线程与互斥锁)

一.锁的概念. 锁,通常被用来实现共享数据的访问,为每一个共享的数据,创建一个Lock对象(一把锁),当需要访问这个共享的资源时,可以调用acquire方法来获取一个锁的对象,当共享资源访问结束后,在调用release方法去解锁. 二.python中的互斥锁. 在介绍互斥锁之前,先来一起看一个例子.(每个线程对num实现一次-1的操作) import threading import  time num = 200  #每个线程都共享这个变量. tread_list = [] def count

11.python并发入门(part12 初识协程)

一.协程的简介. 协程,又被称为微线程,虽然是单进程,单线程,但是在某种情况下,在python中的协程执行效率会优于多线程. 这是因为协程之间的切换和线程的切换是完全不一样的!协程的切换是由程序自身控制的(程序的开发者使用yield去进行控制,协程和协程之间的切换是可控制的,想什么时候切换就什么时候切换). 当使用多线程时,开的线程越多,协程的优势就越明显. 协程的另一个优点,就是无需锁机制,因为协程只有一个进程,和线程,不存在多线程或者多进程之间访问公共资源的冲突,所以说,在协程中无需加锁,如

11.python并发入门(part7 线程队列)

一.为什么要用队列? 队列是一种数据结构,数据结构是一种存放数据的容器,和列表,元祖,字典一样,这些都属于数据结构. 队列可以做的事情,列表都可以做,但是为什么我们还要去使用队列呢? 这是因为在多线程的情况下,列表是一种不安全的数据结构. 为什么不安全?可以看下面这个例子: #开启两个线程,这两个线程并发从列表中移除一个元素. import threading import time l1 = [1,2,3,4,5] def pri(): while l1: a = l1[-1] print a

11.python并发入门(part15 关于I/O多路复用)

一.为什么要产生I/O多路复用? 两个主机之间通信,主机A和主机B都需要开启socket,主机A首先要等待客户端来进行连接,这是会发起一个recvfrom的系统调用,如果主机B一直没有去连接主机A,没有给主机A发送任何数据,进程就会被阻塞,无法去做其他的事情(默认的阻塞I/O模型),一直阻塞到主机B去连接主机A,主机A收到了这个连接. 其实这种模式在单服务器,单客户端(两台主机之间单独通信)没有什么问题,如果说是多并发场景呢?服务端阻塞与第一个客户端发来的socket对象中,另外一个客户端2要发

11.python并发入门(part11 进程同步锁,以及进程池,以及callback的概念)

一.关于进程锁. 其实关于进程锁没啥好讲的了,作用跟线程的互斥锁(又叫全局锁也叫同步锁)作用几乎是一样的. 都是用来给公共资源上锁,进行数据保护的. 当一个进程想去操作一个公共资源,它就可以给公共资源进程"上锁"的操作,其他进程如果也想去访问或者操作这个公共资源,那么其他的进程只能阻塞,等待刚刚的进程把锁释放,下一个进程才可以对这个公共资源进行操作. 下面是个关于进程锁的使用示范: #!/usr/local/bin/python2.7 # -*- coding:utf-8 -*- im

11.python并发入门(part10 多进程之间实现通信,以及进程之间的数据共享)

一.进程队列. 多个进程去操作一个队列中的数据,外观上看起来一个进程队列,只是一个队列而已,单实际上,你开了多少个进程,这些进程一旦去使用这个队列,那么这个队列就会被复制多少份. (队列=管道+锁) 这么做的主要原因就是,不同进程之间的数据是无法共享的. 下面是使用进程队列使多进程之间互相通信的示例: 下面这个例子,就是往进程队列里面put内容. #!/usr/local/bin/python2.7 # -*- coding:utf-8 -*- import multiprocessing de

11.python并发入门(part1 初识进程与线程,并发,并行,同步,异步)

一.什么是进程? 在说什么是进程之前,需要先插入一个进程切换的概念! 进程,可以理解为一个正在运行的程序. 现在考虑一个场景,假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.你是不是已经想到在程序A读取数据的过程中,让程序B去执行,当程序A读取完数据之后,让程序B暂停.这当然没问题,但这里有一个关键词:切换. 既然是切换,那么这就涉及到了状态的保存,状态的恢复,加上程序A与

11.python并发入门(part8 基于线程队列实现生产者消费者模型)

一.什么是生产者消费者模型? 生产者就是生产数据的线程,消费者指的就是消费数据的线程. 在多线程开发过程中,生产者的速度比消费者的速度快,那么生产者就必须等待消费者把数据处理完,生产者才会产生新的数据,相对的,如果消费者处理数据的速度大于生产者,那么消费者就必须等待生产者. 为了解决这种问题,就有了生产者消费者模型. 生产者与消费者模型,是通过一个容器,来解决生产者和消费者之间的耦合性问题,生产者和消费者之间并不会直接通信,这样生产者就无需等待消费者处理完数据,生产者可以直接把数据扔给队列,这个