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()

优质内容筛选与推荐>>
1、git安装和git命令:全局设置用户名邮箱配置
2、[译]从零开始成为数据科学家的9个步骤
3、数据结构 图的定义和搜索方法(清晰图解)
4、Hadoop集群内存过高,HDFS存储慢
5、Life Guideline


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号