zoukankan      html  css  js  c++  java
  • Python学习之旅(二十三)

    Python基础知识(22):进程和线程(Ⅰ)

    1、多进程

    (1)fork

    Python的os模块封装了常见的系统调用,其中就包括fork,可以在Python程序中轻松创建子进程

    fork可以在Mac的Python上运行,但无法再Windows下运行

    (2)multiprocess

    multiprocessing模块就是跨平台版本的多进程模块

    multiprocessing模块提供了一个Process类来代表一个进程对象

    #process_1.py
    
    from multiprocessing import Process
    import os
    
    def work(name):
        print("Run child process %s(%s)..." %(name,os.getpid()))
    
    if __name__=="__main__":
        print("Parent process %s." % os.getpid())
        #创建进程实例
        p = Process(target=work, args=("test",))
        print("Child process will start...")
        p.start()
        p.join()
        print("Child process end.")
    
    结果:
    Parent process 14628.
    Child process will start...
    Child process end.

    创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动,join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步

    (3)pool

    用进程池的方式批量创建子进程,启动大量的子进程

    #process_2.py
    
    from multiprocessing import Pool
    import os, time, random
    
    def long_time_task(name):
        print("Run task %s(%s)..." %(name,os.getpid()))
        start=time.time()
        time.sleep(random.random()*3)
        end=time.time()
        print("Task &s runs %0.2f seconds." %(name,(end - start)))
    
    if __name__=="__main__":
        print("Parent process %s." % os.getpid())
        p = Pool(2)
        for i in range(3):
            p.apply_async(long_time_task, args=(i,))
        print("Waiting for all subprocess done...")
        p.close()
        p.join()
        print("All subprocess done")
    
    结果:
    Parent process 2096.
    Waiting for all subprocess done...
    All subprocess done

    Pool的默认大小是CPU的核数,此次运行环境cup核数为1

    (4)子进程

    subprocess模块可以让我们非常方便地启动一个子进程,然后控制其输入和输出

    #process_3.py
    
    import subprocess
    
    print("$ nslookup www.python.org")
    r = subprocess.call(["nslookup", "www.python.org"])
    print("Exit code:", r)
    
    
    结果:
    $ nslookup www.python.org
    Exit code: 0

     如果子进程还需要输入,则可以通过communicate()方法

    (5)进程间通信

    Python的multiprocessing模块包装了底层的机制,提供了QueuePipes等多种方式来交换数据

    #process_4.py
    
    from multiprocessing import Process, Queue
    import os, time, random
    
    def write(q):
        print("Process to write: %s" %os.getpid())
        for value in ["A","B","C"]:
            print("Put %s to queue..." % value)
            q.put(value)
            time.sleep(random.random())
    
    def read(q):
        print("Process to read: %s" % os.getpid())
        while True:
            value = q.get(True)
            print("Get %s from queue." % value)
    
    if __name__=="__mainn__":
        q = Queue()
        pw = Process(target=write, args=(q,))
        pr = Process(target=read, args=(q,))
        pw.start()
        pr.start()
        pw.join()
        pr.terminate()

    二、多线程

    多任务可以由多进程完成,也可以由一个进程内的多线程完成

    进程是由若干线程组成的,一个进程至少有一个线程

    Python的标准库提供了两个模块:_threadthreading_thread是低级模块,threading是高级模块,对_thread进行了封装

    绝大多数情况下,我们只需要使用threading这个高级模块

    import time, threading
    
    def work():
        n = 1
        while n < 6:
            print("Work %s is running..." % str(n))
            n+=1
    
    t = threading.Thread(target = work, name = "workThread")
    t.start()
    t.join()
    print("%s ended." % threading.current_thread().name)
    
    
    结果:
    Work 1 is running...
    Work 2 is running...
    Work 3 is running...
    Work 4 is running...
    Work 5 is running...
    MainThread ended.

    由于任何进程默认就会启动一个线程,我们把该线程称为主线程,主线程又可以启动新的线程,Python的threading模块有个current_thread()函数,它永远返回当前线程的实例

    主线程实例的名字叫MainThread,子线程的名字在创建时指定,名字仅仅在打印时用来显示,完全没有其他意义,如果不起名字Python就自动给线程命名为Thread-1Thread-2……

    LOCK

    线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改

    线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了

    当某个进程要更改数据时,先给它上锁,其它线程不能更改。只有当锁被释放后,其它线程获得该锁以后才能改

    由于锁只有一个,无论多少线程,同一时刻最多只有一个线程持有该锁,所以,不会造成修改的冲突

    多核CPU

    Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响

  • 相关阅读:
    高级(线性)素数筛
    Dijkstra(迪杰斯特拉)算法
    简单素数筛
    【解题报告】 POJ1958 奇怪的汉诺塔(Strange Tower of Hanoi)
    4 jQuery Chatting Plugins | jQuery UI Chatbox Plugin Examples Like Facebook, Gmail
    Web User Control Collection data is not storing
    How to turn on IE9 Compatibility View programmatically in Javascript
    从Javascrip 脚本中执行.exe 文件
    HtmlEditorExtender Ajax
    GRIDVIEW模板中查找控件的方式JAVASCRIPT
  • 原文地址:https://www.cnblogs.com/finsomway/p/10062327.html
Copyright © 2011-2022 走看看