多进程理论知识:

开发人员用到多线程多进程是在服务器端

测试人员用到的是性能测试

面试常问  

进程和线程的区别?请你谈谈你对进程和线程的理解?

python多进程执行和多线程执行哪个效率高?为什么多进程比多线程效率高?

loadrunner并发方式:使用线程(默认多线程);使用进程

多线程的程序如何测试?

面试问题:单线程和多线程在性能测试时分别适用于哪种场景?

面试问题:loadrunner工作原理?什么时候用多线程,什么时候用多进程?为何推荐使用多进程?

LRU  最近最少使用页面置换算法;大型系统都是玩缓存的  缓存是多线程的;多线程-乱序

新系统测法--压死为止;  老系统-水平扩展,通过加机器来解决瓶颈;从业务上控制:别老秒杀、加机器

性能测试的核心:性能测试方案,通过现有业务量做预估  如双十一

看看网络通讯原理;

TCPUDP的区别?TCP 传输通讯协议 三次握手?

Transmission Control Protocol传输控制协议;建立一个连接需要三次握手,而终止一个连接要经过四次握手

TCP三次握手的过程如下:

客户端发送报文给服务器端“给你发消息了收到了吗?->服务器端收到报文,回应一个”收到了!“

->客户端收到服务器端回应的报文后,回应一个”好的!“

三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。

 

进程的定义:

计算机里运行的一个程序;是系统进行资源分配和调度的基本单位;进程是基本的分配单元,也是基本的执行单元。进程是线程的容器。

线程归属于进程,跟进程共用一块内存

进程是一个内核级的实体,进程结构的所有成分都在内核空间中,一个用户程序不能直接访问这些数据。

 

LINUX系统中看进程:

ps -ef

一个进程至少包含一个线程,

CTRL+Z将进程暂停

计算机组成指的是系统结构的逻辑实现,包括机器机内的数据流和控制流的组成及逻辑设计等。主要分为五个部分:控制器,运算器,存储器,输入设备,输出设备。

 

进程状态:

创建、就绪、运行、阻塞、结束

死锁:互相等待

阻塞:进程主动发起,需要等一些事完成了才能继续往下走

 

进程的概念主要有两点:

第一,进程是一个实体。每一个进程都有它自己的地址空间,进程包括:

文本区域作用:存储处理器执行的代码)、

数据区域作用:存储变量和进程执行期间使用的动态分配的内存)、

堆栈区域作用:存储活动过程调用的指令和本地变量)

 

第二,进程是一个“执行中的程序”。

程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。

 

多任务通常指的就是多进程

是多任务系统出现后,为了刻画系统内部出现的动态情况,描述系统内部各程序的活动规律引进的一个概念,所有多任务设计操作系统都建立在进程的基础上。


进程特性:

动态性、

并发性(操作系统有多个进程)、

独立性(各用各的内存)、

异步性、

结构性(进程由程序、数据和进程控制块三部分组成)、

多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果;但是执行过程中,程序不能发生改变。

 

 

CPU

运算器(进行数据运算)、

控制器(发出控制信号,统一指挥和协调计算机各器件进行工作)、

寄存器(CPU内部高速独立的暂时存储单元(容量很小))

 

计算机的三级缓存?越低级别内存越大但速度越慢

三级缓存是为读取二级缓存后未命中的数据设计的—种缓存,在拥有三级缓存的CPU中,只有约5%的数据需要从内存中调用,这进一步提高了CPU的效率。其运作原理在于使用较快速的储存装置保留一份从慢速储存装置中所读取数据且进行拷贝,当有需要再从较慢的储存体中读写数据时,缓存(cache)能够使得读写的动作先在快速的装置上完成,如此会使系统的响应较为快速。

 

进程如何切换:

操作系统为了控制进程的执行,必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行,这种行为被称为进程切换,任务切换或上下文切换。

或者说:

进行进程切换就是从正在运行的进程中收回处理器,然后再使待运行进程来占用处理器

举例理解:

这就像多个同学要分时使用同一张课桌一样,所谓要收回正在使用课桌同学的课桌使用权,实质上就是让他把属于他的东西拿走;而赋予某个同学课桌使用权,只不过就是让他把他的东西放到课桌上罢了。

在切换时,一个进程存储在处理器各寄存器中的中间数据叫做进程的上下文,所以进程的切换实质上就是被中止运行进程与待运行进程上下文的切换。在进程未占用处理器时,进程的上下文是存储在进程的私有堆栈中的。

 

进程运行状态:

运行中的进程具有三种状态:就绪状态、运行状态、阻塞状态

 

一核只能一个进程;

一台机器最多能开多少线程?Jmeter里有个线程组 150-200

要了解CPU工作的原理并发和并行又有区别,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。

多进程编程 有意义

名词:

原语:不可被分割的一段程序

由若干个机器指令构成的完成某种特定功能的一段程序,原语的执行必须是连续的,在执行过程中不允许被中断。

创建1个进程就是1个原语

内存(主存):

指的是内存条,直接给CPU提供存储、高速、低容量、价格贵,不能永久保存数据,断电消失,需要从辅存中重新调入数据。

外存(辅存):

指硬盘、光盘、U 盘等,给主存提供数据、低速、大容量、价格低,能永久保存数据。所以更高缓存的CPU和更大的内存能够大大提升系统的性能.

缓存:

缓冲寄存器,在CPU同时处理很多数据,而又不可能同时进行所有数据的传输的情况,把优先级低的数据暂时放入缓存中,等优先级高的数据处理完毕后再把它们从缓存中拿出来进行处理

死锁:

永远在互相等待的进程称为死锁进程

挂起:

操作系统对在内存中的程序进行合理的安排,其中有的进程被暂时调离出内存,当条件允许的时候,会被操作系统再次调回内存,重新进入就绪态(等待被执行的状态)

僵尸进程:

父进程已死子进程未死

 

同步、异步、阻塞和非阻塞

非阻塞-就是继续运行

阻塞-停止等这活干完了再执行

同步-顺序执行

异步-乱序并行执行

一般异步非阻塞配合使用的,这样才能发挥异步的效用。

 

进程的五态模型

时间片(操作系统控制的)到是CPU给每个任务执行的时间是有限的,时间到了就踢出来了


 

活跃在内存

静止在硬盘

 

进程的创建过程

1)申请进程控制块PCB 2)为新进程分配资源;3)初始化进程块;4)将新进程插入就绪队列

 

指针:

地址的地址就是指针;

计数器?

程序计数器是用于存放下一条指令所在单元的地址的地方。

程序计数器是计算机处理器中的寄存器,它包含当前正在执行的指令的地址(位置)。当每个指令被获取,程序计数器的存储地址加一。在每个指令被获取之后,程序计数器指向顺序中的下一个指令。当计算机重启或复位时,程序计数器通常恢复到零。

作用:为了保证程序(在操作系统中理解为进程)能够连续地执行下去,处理器必须具有某些手段来确定下一条指令的地址。而程序计数器正是起到这种作用,所以通常又称为指令计数器。

 

进程的终止:

正常终止(表示进程已经运行完成)、

异常终止(程序出现某些错误和故障而迫使进程终止,如算术运算错,I/O故障)、

外界干预(人工干预、父进程终止)

 

进程的终止过程

1)PCB集合中检索出要终止的进程的PCB

2)若被终止进程正处于执行状态,应立即终止该进程的执行,并置调度标志为真表示被终止后可重新被调度。

3)若该进程还有子孙进程终止所有子孙进程;

4)将全部资源归还给系统;

5)PCB从所在队列中移出

 

 

Python进程

linux系统操作命令:

新建文件夹:mkdir xumian

查看目录:  ls -lrt

进入目录: cd ~/xumian

新建并编辑文件: vi 文件名 如:vi 1.py

进入编辑模式,将代码贴进来,写完后,先按下ESC退出编辑模式,然后

输入w是保存;

输入wq 保存并退出,回到命令界面

显示当前目录: pwd

显示当前目录下的文件:lsdir

往回删除一个单词:ctrl + w

进入程序所在目录,输入python 1.py

上传文件:rz+回车

删除文件夹实例:

rm -rf /var/log/httpd/access

将会删除/var/log/httpd/access目录以及其下所有文件、文件夹

删除文件使用实例:

rm -f /var/log/httpd/access.log

将会强制删除/var/log/httpd/access.log这个文件

回车换行

esc + i + enter

esc + i + backspace

删除一行:

vi模式下  连续输入两次小写的d,即dd,就可以成功删除

查看当前目录:pwd

 

 

os.fork  (只在linux上有)

1:文件名字a.py

#encoding=utf-8

import os

print os.getpid()  #当前程序a.py的进程id

 

pid = os.fork() # a.py创建一个子进程

print pid  #子进程真正的id和规定os.fork规定是0pid  fork函数返回值

if pid == 0:  #创建了一个子进程pid0,规定就是子进程拿到就是0子进程执行了if

  print 'I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid())

else:  #父进程执行elseos.getpid当前进程id;osgetppid表示父进程的id

#父进程:a.py的父进程 编译器自己搞出来的;谁执行就会打印谁的id

  print 'I (%s) just created a child process (%s).' % (os.getpid(), pid) 

解释:两个进程的唯一区别是fork的返回值。子进程接收返回值0,而父进程接收子进程的pid作为返回值。一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID

关于os.fork()的进程的执行顺序:执行不执行看调度程序。是要看操作系统如何进行进程调度的,具体看调度算法。比如,如果基于时间片轮转调度算法,假设父进程先执行,本时间片内没有执行完,则会发生进程切换,即调度程序从就绪队列中取出一个进程在下一个时间片内执行,而本进程保存进程信息和状态然后插入就绪队列,等待调度程序重新调度。

 

 

xshell  连接:

39.106.41.11  端口号:22  student  gloryroad987!

 

 

multiprocessin 创建进程

多进程是乱序的互相之间无影响的

Process类的构造方法:

help(multiprocessing.Process)

__init__(self, group=None, target=None, name=None, args=(),

kwargs={})

参数说明:

group:进程所属组,基本不用。

target:表示调用对象,一般为函数。港口工人搬沙包,工人就是一个进程,搬沙包是工作,进程就是生成了一个工人,指定工人去干搬沙包这个活儿。target表示我起了一个进程,要工作的内容是谁;表示进程生成了会执行target指定的函数作为该进程的执行任务。

args:表示调用对象的位置参数元组。指定函数的参数。

name:进程别名。

kwargs:表示调用对象的字典。给函数传递keyvalue参数,传递字典作为参数

 

2压力测试程序的本质,最简单的压力测试模型

#coding=utf-8
#该题表示生成了5个进程每个进程执行了一遍do函数然后结束
import multiprocessing
#help(multiprocessing.Process)
#print multiprocessing.current_process()
#print multiprocessing.current_process().name

def do(n) :   #传入参数n   do函数就干了两件事:打印进程starting,打印worker
  #获取当前线程的名字
    name = multiprocessing.current_process().name
    print name,'starting'  #打印进程名字,加starting,表示当前进程启动了
    print "worker ", n   #表示第几个worker
    return
#子进程只执行do函数;主进程只执行main下面的内容
if __name__ == '__main__' :#必须写,表示执行的是文件本身不是被当作包引用就会执行下面所有代码
    numList = [] #存的是进程对象,所以打印时是进程对象的字符串表示
    for i in xrange(5) : #主进程会在循环中依次生成5个子进程子进程会同时执行do函数;循环5次:0-4
        p = multiprocessing.Process(target=do, args=(i,))#精髓:生成进程对象;
        # target指定的函数就是子进程要执行的,子进程只执行函数内容
        #print p
        #do函数作为进程执行的任务;args=(i,)表示是i作为do函数的参数
        #p = multiprocessing.Process(target=do, args=(i,),name='xm'+str(i))  #给进程命名
        numList.append(p) #进程对象加到list
        p.start() #进程p做了一个启动:进程开始执行do函数;去掉的话子进程不会执行
        #p.close() #join前面必须有close
        p.join() #(顺序执行)表示进程运行结束后还会继续运行下面(主进程)的代码
    #没有join表示不等函数完成就继续执行,join删掉就是并发了
        print "Process end."
    print numList #打印list5个进程的内容

 

练习1:用2个进程去读取硬盘两个不同的文件,并且打印文件的内容。进程全部执行内容输出后,打印一句"done!"

#coding=utf-8
import multiprocessing
def readfile(path):
    with open(path) as f:
        print f.read()

if __name__=="__main__":
    file_list=["E:\\x.txt","E:\\y.txt"]
    for i in range(len(file_list)):
        p = multiprocessing.Process(target=readfile, args=(file_list[i],))
        p.start()
        p.join()  ##join表示进程1全部执行完毕时才会进行第2次循环去掉后会实现并发
    print "Done!"

 

 

练习2:如何做到进程并发执行且全执行完后再打印Done

#encoding=utf-8

import multiprocessing

import time

def readfile(path):#子进程执行

    #time.sleep(5)     #如果去掉主进程中的join在子进程中sleep 5秒那print Done就会先执行

    with open(path) as f:

        print f.read()

 

if __name__=="__main__":#主进程执行

    file_list=["E:\\x.txt","E:\\y.txt"]

    process_list=[]

    for i in range(len(file_list)):

        p = multiprocessing.Process(target=readfile, args=(file_list[i],))

        process_list.append(p)

 

    for i in process_list:#上面的列表已经生成了,这里遍历;进程同时启动,最后都完成了才打印print

        i.start()#没有start的话子进程不会启动;2个进程同时都启动了

for i in process_list:   #这个for循环是同步的概念

    #pass

        i.join() #先把进程1执行完后才会执行进程2join  #这个进程的代码执行完毕了才会执行主进程代码

print "Done!"

 

3LINUX上执行的例子:

多进程并发不考虑谁先谁后没有意义;如果需要进程有先后那就要用到进程间通讯了

#!/usr/bin/python

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

from multiprocessing import Process  

import os  

import time  

 

def sleeper(name, seconds):  #子进程执行该函数

    print "Process ID# %s" % (os.getpid())  #获取当前子进程id

    print "Parent Process ID# %s" % (os.getppid())   #当前py文件的id

#仅支持在linux,一个进程会有父进程和自己的IDwindows上就没有父进程id

    print "%s will sleep for %s seconds" % (name, seconds)  

    time.sleep(seconds)

# if __name__ == "__main__":   #主进程执行该函数

child_proc = Process(target = sleeper, args = ('bob', 5))  

child_proc.start() #启动子进程,主进程和子进程各自同时运行谁也不影响谁

print "in parent process after child process start"  

print "parent process about to join child process"

child_proc.join()  #join要等子进程完成才能执行

print "in parent process after child process join"  

print "the major process: %s" % (os.getpid())  #主进程的id

print "the parent's parent process: %s" % (os.getppid())  #主进程的父进程:编译器id

 

------

再试这个:

#encoding=utf-8

from multiprocessing import Process

import os

import time

 

def sleeper(name, seconds):

    print "Process ID# %s" % (os.getpid())

    print "Parent Process ID# %s" % (os.getppid())

#仅支持在linux,一个进程会有父进程和自己的IDwindows上就没有父进程id

    print "%s will sleep for %s seconds" % (name, seconds)

    time.sleep(seconds)

# if __name__ == "__main__":

child_proc = Process(target = sleeper, args = ('bob', 5))

child_proc.start()

print "in parent process after child process start"

print "parent process about to join child process"

child_proc.join()

print "in parent process after child process join"

print "the parent's parent process: %s" % (os.getppid())


服务器端性能测试不需要考虑渲染

 

linux可以做什么?

 

4:多进程模板程序:向网站服务器发起压力请求  用时往里套,应用场景:接口、自定义协议、

#encoding=utf-8

import multiprocessing

import urllib2

import time

 

def func1(url):#访问网站的方式

  response = urllib2.urlopen(url) #url打开网站

  html = response.read()  #read把网站源码读下来,读到变量里

  print html[0:20]  #只打印前20个字符

  time.sleep(20)

  #print html[20:40]  #去掉join时候去掉注释看效果

 

def func2(url) :

  response = urllib2.urlopen(url)

  html = response.read()

  print html[0:20]

  time.sleep(20)

  #print html[20:40]

 

if __name__ == '__main__' :

    p1 = multiprocessing.Process(target=func1,args=("http://www.sogou.com",),name="gloryroad1")

    p2 = multiprocessing.Process(target=func2,args=("http://www.baidu.com",),name="gloryroad2")

    p1.start()

    p2.start()

    p1.join()

    p2.join()

    time.sleep(10)

    print "done!"

 

5:测单进程和多进程的执行效率

多进程是乱序的,2个进程往同一个打印区域同时打印东西,出来内容就乱了

#coding: utf-8

import multiprocessing

import time

def m1(x):

    time.sleep(0.01)

    return x * x

 

if __name__ == '__main__':

pool = multiprocessing.Pool(multiprocessing.cpu_count())  #获取CPU的核数,pool表示进程池

#使用cpu核数作为进程数量

    i_list = range(1000)

    time1=time.time()

pool.map(m1, i_list)  #map函数用进程池做计算,process时候需要用start其他都不用!

#依次用m1函数去执行,i_list每一个作为参数传到m1函数里,然后把结果放一个list中返回

    time2=time.time()

print 'time elapse:',time2-time1  

#以上是并发的

    #以下是单进程的,主进程执行

    time1=time.time()

    map(m1, i_list)

    time2=time.time()

    print 'time elapse:',time2-time1

 

>>> map(str,[1,2,3])

['1', '2', '3']

>>> map(str,[1,2,3,4])

['1', '2', '3', '4']

 

 

import multiprocessing

multiprocessing.cpu_count()  #获取CPU几个核

 

linux下看有几个核  top    或:   cat /proc/cpuinfo

 

Pool进程池

Pool类中的方法

map()

函数原型:map(func, iterable[, chunksize=None])

把迭代对象的每一个值传到函数中做执行

Pool类中的map方法,与内置的map函数用法行为基本一致,它会使进程阻塞直到返回结果。

close()

关闭进程池(Pool),不是杀进程而是:使其不再接受新的任务。派完活了一定要close

terminate()

立刻结束工作进程,不再处理未处理的任务。

join()

使主进程阻塞等待子进程的退出,join方法必须在closeterminate之后使用。

获取CPU的核数

multiprocessing.cpu_count() #获取cpu的核数

 

 

6

#coding: utf-8

import multiprocessing

import os

import time

import random

def m1(x):

    time.sleep(random.random()*1)

    print "pid:",os.getpid(),x*x   #打印每个进程号,自动分配的,能看到哪个进程干活

    return x * x

if __name__ == '__main__':

    pool = multiprocessing.Pool(multiprocessing.cpu_count())  #进程就是工人数

    #pool = multiprocessing.Pool(8) #电脑是4核,虽然生成了8个进程但cpu利用率没有那么高

    #print multiprocessing.cpu_count()

    i_list = range(8)  #range是要干的活,写几都可以

    print pool.map(m1, i_list)

#pool.close()  #close后不能再派活,进程池需要关

#print pool.map(m1, i_list)  #close后再派活会抛异常

    #pool.join()

    print "Done"

 

7:创建简单的进程池-不用分配拿来就用

异步:不用等活干完继续往下走

#encoding=utf-8

from multiprocessing import Pool

import time

 

def f(x):

    #time.sleep(3) #如果有这句话会抛TimeoutError异常

    return x * x

 

if __name__ == '__main__':

    pool = Pool(processes = 4)      # start 4 worker processes

    result = pool.apply_async(f, [10])  # evaluate "f(10)" asynchronously  #async表示异步

    print result.get(timeout = 1)  #固定写法:等1秒要取到result没取到就抛异常

print pool.map(f, range(10))   # prints "[0, 1, 4,..., 81]"返回值放list

 

8:多进程是乱序

#encoding=utf-8

from multiprocessing import Pool

import time

import os

 

def f(x):

    print "work:",os.getpid()

    time.sleep(3)

    return x * x

 

if __name__ == '__main__':

    pool = Pool(processes = 4) #生成4个进程

    result = pool.apply_async(f, [10])

    result1 = pool.apply_async(f, [10]) #不用管会自动加进程

    result2 = pool.apply_async(f, [10])

    print result.get(timeout = 4)

    print pool.map(f, range(10))

多进程并行执行

 

 

9:传入多个参数

#encoding=utf-8

from multiprocessing import Pool

import os

import time

 

def f(x,y):

    print "worker:",os.getpid()

    time.sleep(3)

    return x * y

 

if __name__ == '__main__':

    pool = Pool(processes = 4)      # start 4 worker processes

    #print help(pool.apply_async)

result = pool.apply_async(f, args=(10,4))  # evaluate "f(10)" asynchronously  

#result是个对象,104作为参数传给函数

#异步就是不等

    print result.get(timeout = 4)

 

 

总结:

谈到子进程,意思是主进程中生成的新的进程,我们是用fork子进程的方式,就是指定一个函数和函数的参数给子进程,start之后,子进程开始执行,如果执行完了,子进程就退出了,在子进程执行的同时,主进程也在执行他的代码。

 

主进程和子进程的执行没有任何关联

 

除非使用join,才可以让主进程和子进程的执行有关联

 

如果使用了join,主进程会等子进程执行完毕,才会执行join语句后面的主进程代码

 

使用pool进程池,指定进程池大小--》启动几个进程

 

如果使用apply_async函数,则使用异步方式执行指定的函数(同时需要指定的函数参数),主程序会继续执行apply_async函数后的其他语句,不会等待apply_async函数执行完毕。

 

进程池会自动选择一个进程执行apply_async函数中指定的函数任务,我们无需关注

 

如果使用pool.map 则进程池会自动使用多个进程来完成任务,我们无需关注

哪些进程完成了任务,这是pool封装的功能

如果想在进程池的任务全部执行后,再执行主程序,需要使用pool.join()。      多进程异步才有意义。

 

 

20171115日晚 复习

什么是进程?

计算机中运行的特定数据的程序,是操作系统分配资源的基本单元。

下一个问题:进程和线程有什么区别?

进程包含线程,进程至少有一个主线程在执行,也可以有多个线程。

进程有自己的独立使用内存,每个进程使用的内存区域都是独立的。

线程使用的内存区域都是进程中的内存,在一个进程中多线程使用的

内存都是在当前进程中的。

 

进程由什么组成的?

3部分:

文本区域:存程序

数据区域:动态分配的内存

堆栈:变量

 

进程由哪些状态组成的呢?

创建:分配内存,pcb控制器初始化

就绪:进入就绪队列,等待cpu去执行,处于等待状态

运行:就是在cpu中运行

阻塞:进程等待其他进程的数据,或者是IO,或者其他事情的发生

退出:进程释放资源

 

进程退出有几种方式:

1 正常退出,也就是程序执行完毕

2 程序崩溃了,导致不得不退出

3 外部干预,kill -9 ,比如CTRL+C

 

原语:

不可分割的一组指令,必须一起执行完,且不能中断

 

同步:

顺序执行,且下一个步骤必须在上一个步骤完成后才可以执行。

 

异步:

不需要顺序执行,可以并行执行的操作。

同步异步应用场景:

用户需要立刻看到结果的:同步

注册用户后要登录   要用同步

用户不需要立刻看到的:异步

注册的时候用户名排重判断,用的ajax

如博客发布,其他用户看到的信息流,异步后台发的,什么时候发不影响用户操作

 

阻塞:

等待一个事件的完成,是由进程主动发起。

 

非阻塞:

不等某个事件的完成,直接继续执行。

 

 

挂起:

程序暂时处于阻塞状态,等待某个事件的完成。

 

主进程、子进程:

 

linuxos.fork()

一段代码:分别由主进程和子进程同时执行

pid = os.fork()

 (主进程执行,对于主进程来说pid是子进程的进程号)

对于子进程来说pid拿到的是0

 

 

怎么生成一个进程:

p=multiprocessing.process(taraget=函数,args=(yyy,zzz),name ="xxx")

p.start()

p.join()

print "done!"

 

练习:如果我想生成更多的进程,我还怎么做?

1 使用for循环的方式,生成多个进程。

2 使用进程池

 

分别使用上面2种方式,生成2个进程。

 

解法1

 

#encoding =utf-8

import multiprocessing

from multiprocessing import Pool

import time

def do1(n) :

 

  result = 1

  for i in range(1,n):

      result = result*i

  print result

  return

 

def do2(n) :

  for i in range(n):

    time.sleep(0.01)

  print "sleep long time!"

  return "sleep long time!"

 

if __name__ == '__main__' :

 

  pool = Pool(processes=4)  # start 4 worker processes

  result1 = pool.apply_async(do1, [26])  

  result2 = pool.apply_async(do2, [50])

  pool.close()

  result1.get(timeout=1)

  result2.get(timeout=1)

  print "Process end."

 

解法2

#encoding =utf-8

import multiprocessing

import time

def do1(n) :

 

  result = 1

  for i in range(1,n):

      result = result*i

  print result

  return

 

def do2(n) :

  for i in range(50):

    time.sleep(0.01)

  print "sleep long time!"

  return

 

if __name__ == '__main__' :

  targetList = [do1,do2]

  argsList = [26,50]

  process_list = []

  for i in xrange(2) :

    p = multiprocessing.Process(target=targetList[i], args=(argsList[i],))

    process_list.append(p)

  for i in process_list:

      i.start()

  for i in process_list:

      i.join()

 

  print "Process end."