• 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锁,互不影响

  • 相关阅读:
    gdb调试libtool封装的可执行文件
    转载 Linux top命令详解
    VirtualBox使用物理硬盘建立磁盘
    【sqlServer】常用语句整理
    【c#基础】特殊集合
    【c# 基础】各种集合的不同情况下的性能
    【c#集合】Lookup 类 有序字典 SortedDictionary<TKey,TValue> 集
    【c#基础】集合--栈Stack 链表 LinkList 有序列表SortedList 字典Dictionary
    【c#基础】集合
    【c#基础】委托、Lambda表达式和事件
  • 原文地址:https://www.cnblogs.com/finsomway/p/10062327.html
Copyright © 2020-2023  润新知