9、进程、线程

一、进程

1linux下使用fork()函数创建多进程,调用fork()函数时,linux操作系统可以返回两个进程,一个是本身,一个是子进程;

import os

os .fork()     #创建一个子进程

os.getpod()      #得到子进程的进程号(os模块的一个方法)

os.getppid()      #得到父进程的进程号

 

2、跨平台的多进程模块multiprocessing,该模块提供了一个Process类来代表一个进程对象

from multiprocessing import Process

import os

def run(name):

print("%s process=(%s)"%(name,os.getpid()))

 

print ('Parent process %s',%os.getpid())      #打印父进程的进程号

p=Process(target=run,args=('test',))  #创建一个子进程对象,该对象需传入执行函数及函数的参数;

p.start()      #start()方法启动进程,会执行函数的内容打印子进程的进程号

p.join()       #join()方法可以等待子进程结束后再继续往下运行;

 

3、进程池Pool类批量创建子进程apply_async()方法

from multiprocessing import Pool

import os ,time,radom

def(name):

print('task %s(%s)'%(name,os.getpid()))

p = Pool(4)      #创建一个Pool对象,Pool对象需传入参数,参数默认大小是CPU的核数

for i in range(5):

p.apply_async(run,args = (i,))

p.close()      #进程池在调用join前,需先调用close,调用close后就不能添加新的Process了;

p.join()      #调用join()方法会等待所有子进程执行完毕,程序才会继续往下运行;

 

4subprocess模块启动子进程使用call()方法,以及communicate()方法

import subprocess

r.subprocess.call(['nslookup','www.python.org')   #

print ('Exit code:',r)

 

 

 

import subprocess

p = subprocess.Popen(['nsloopup'],stdin=subprocess.PIPE,stdout=subprocess,PIPE,stderr=subprocess.PIPE)

output,err = p.communicate(b'set q=mx\npython.org\nexit\n')

print(output.decode('utf-8'))

print('Exit code:',p.returncode)

 

5、进程间通信以Queue对象为媒介来交换数据;进程间通信还可以通过Pipes来实现;

from multiprocessing import Process Queue

import os, time,random

def write(q):   #Queue里写数据的函数

for value in ['A','B','C']:

print('Put %s to queue...'% value)

q.put(value)

def read(q):    #Queue里读数据的函数

while Ture:

value = q.get(Ture)

print('Get %s from queue.'% value)

 

q = Queue()   #父进程创建Queue并传递给各个子进程;

pw = Process(target=write,args=(q,))

pr = Process(target=read,args=(q,))

pw.start()   #启动子进程

pr.start()    #启动子进程

pw.join()      #等待pw结束

pr.terminate()  #pr进程是死循环,无法等待其结束,只能强行终止

 

二、线程

1threading模块创建多线程,current_thread()函数返回当前线程的实例,

import time,threading

def loop():

print('thread %s is running...'%threading.current_thread().name)

n=0

while n<5:

n=n+1

print('thread %s >>>%s'%(threading,current_thread().name,n))

time.sleep(1)

print('thread %s is running...'%threading.current_thread().name)  #主线程

t = threading.Thread(target=loop,name='LoopThread')   #子线程

t.start()

t.join()

print('thread %s ended.'% threading.current_thread().name) #主线程

 

2threading.Lock()对象实现创建锁,acquire()方法获取锁,release()方法释放锁

import time,threading

balance = 0

block = threading.Lock()  #创建锁

def change_it(n):

global balance

balance = balance + n

balance = balance - n

def run_thread(n):

for i in range(10000):

lock.acquire()   #获取锁

try:

change_it(n)

finally:

lock.release()    #释放锁

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)

 

3、多核cpu

c c++java 写多线程的死循环可以把核心跑满,但python不会,python解释器执行时有一个GIL锁,每执行100条字节码,解释器会释放GIL锁,让别的线程执行,再多的线程也只能用到1个核;

 

4ThreadLocal变量是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。ThreadLocal解决了参数在一个线程中各个函数之间互相传递的问题。

import threading

local_school = threading.local()  #创建全局Threading.local对象

def process_student():

std = local_school.student   # 获取当前线程关联的student

print('Hello,%s(in %s)' %(std,threading.current_thread().name))

def process_thread(name):

local_school.student = name   #绑定ThreadLocalstudent

process_student()

t1 = threading.Thread(target = process_thread,args=('Alice',),name='Thread-A')

t2 = threading.Thread(target = process_thread,args=('Bob'),name='Thread-B')

t1.start()

t2.start()

t1.join()

t2.join()

 

posted @ 2017-04-10 10:43  摩柯萨青  阅读(130)  评论(0编辑  收藏  举报