• 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 python.org exit ')

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

  • 相关阅读:
    cocos2dx打飞机项目笔记七:各种回调:定时器schedule、普通回调callFunc、菜单回调menu_selector、事件回调event_selector
    cocos2dx打飞机项目笔记六:GameScene类和碰撞检测 boundingbox
    [Redis] 手动搭建标准6节点Redis集群(docker)
    [JavaSE 源码分析] 关于HashMap的个人理解
    [leetcode 周赛 150] 1161 最大层内元素和
    [leetcode 周赛 150] 1160 拼写单词
    [leetcode 周赛 149] 1157 子数组中占绝大多数的元素
    [leetcode 周赛 149] 1156 单字符重复子串的最大长度
    [leetcode 周赛 149] 1155 掷骰子的N种方法
    [leetcode 周赛 149] 1154 一年中的第几天
  • 原文地址:https://www.cnblogs.com/quyong/p/6687884.html
Copyright © 2020-2023  润新知