zoukankan      html  css  js  c++  java
  • python进程和线程

    1.多进程

    针对unix/linux操作系统会提供一个fork()系统调用,其调用一次,返回两次,因为操作系统自动把当前文件复制了一份,称为父进程和子进程

    子进程永远返回0,而父进程返回子进程的ID,这样一个父进程可以fork出很多子进程,so父进程要记下每个子进程的ID,而子进程通过调用getppid()拿到父进程的ID

    python中的os模块封装了常见的系统调用,其中包括fork

    1)Mutiprocessing

    跨平台版本的多进程模块,提供process类来代表一个进程对象

    from multiprocessing import Process
    import os
    #子进程要执行的代码
    def run_proc(name):
        print("run child process %s(%s)..."%(name,os.getpgid()))
    if _name_== '_main_':
        print(("parent process %s"%os.getpgid()))
        p = Process(target=run_proc,args=("test",))
        print("child process will start")
        p.start()
        p.join()
        print("child will end")

    2)pool

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

    from multiprocessing import Process
    import os,time,random
    #子进程要执行的代码
    def long_time_task(name):
        print("run child process %s(%s)..."%(name,os.getpgid()))
        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.getpgid()))
        p = pool(4)
        for i in range(5):
            p.apply_async(long_time_task,args=(i,))
        print("waiting for all subprocesses done")
        p.start()
        p.join()
        print("All subprocesses done")'

    3)子进程

    subprocess模块可以方便的启动一个子进程

    import subprocess
    print("$ nslookup www.python.org")
    r = subprocess.call(["nslookup","www.python.org"])
    print("Exit code",r)

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

    import subprocess
    print("$ nslookup")
    p = subprocess.Popen(["nslookup"],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)

    4)进程间通信

    process之间需要通信,python的multiprocessing模块包装了底层的机制,提供了QueuePipes等多种方式来交换数据

    以Queue为例,一个往Queue里面写入数据,一个从Queue里面读数据

    def read(q):
        print("process to read:%s"%os.getpgid())
        while True:
            value = q.get(True)
            print("get %s from queue"%value)
    if _name_ = "main_":
        q =Queue()
        pw =Process(target = write,args=(q,))
        pr = Process(target=read,args=(q,))
        pw.start()
        pr.start()
        pw.join()
        pr.terminate()

    2.多线程

    python提供了连个模块,一个是_thread和threading,前者是低级模块,后者是高级模块,高级模块对低级模块进行了封装,绝大多数我们使用高级模块

    import time,threading
    def loop():
        print("thread in 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  ended"%threading.current_thread().name)
    print("thread %s is runing"%threading.current_thread().name)
    t = threading.Thread(target=loop,name = "Looptaread")
    t.start()
    t.join()
    print("thread %s  ended"%threading.current_thread().name)

    1)lock

    多线程和多进程的最大区别在于,多进程中每一个变量都有各自的备份,备份在每一个进程中,互不影响,而在多线程中,所有变量由所有线程共享,线程之间共享的问题在于多个线程同时更改一个变量,我们用锁实现,即threading_lock

    import threading
    balance = 0
    lock = threading.Lock()
    def run_thread(n):
        for i in range(1000):
            #先获取锁
        lock.acquire()
        try:
            change_it(n)
        finally:
            #释放锁
            lock.release()

     3.ThreadLocal

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

    import threading
    local_school = threading.local()
    def process_student():
        std = local_school.student
        print("hello,%s(in %s)"%(std,threading.current_thread().name))
    def process_thread(name):
        local_school.student= name
        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()

    4.进程vs.线程

    多进程的最大优点在于稳定性高,缺点在于创建进程的代价大

    多线程通常比进程快一点,致命缺点在于任何一个进程崩溃可能直接造成整个进程坏掉,因为所有进程共享进程内存

    5.分布式进程

    6.正则表达式

    d:匹配一个数字

    w:匹配一个字母或数字

    .:可以匹配任意字符

    *:匹配任意个字符

    +:匹配至少一个字符

    ?:表示匹配一个或者0个字符

    {n}表示n个字符,用{你,m}表示n-m个字符

    对于特殊字符进行转义:

    []:表示更加精确的匹配

    |:表示或

    ^:表示行的开头

    ^d:表示以数字开头

    $:表示结束

    d$:表示必须以数字结束

    re模块,包含所有的正则表达式

    以及使用match模块判断是否匹配成功

    切分字符串:

    分组:用()表示提取的分组,用Match()对象上的group()方法提取子串

    贪婪匹配:匹配尽可能多的字符

  • 相关阅读:
    find the most comfortable road
    Rank of Tetris
    Segment set
    Codeforces Round #380 (Div. 2)D. Sea Battle
    A Bug's Life
    Is It A Tree?
    N皇后问题
    符号三角形
    2016 ICPC总结
    Sudoku Killer
  • 原文地址:https://www.cnblogs.com/quanmeng/p/11939723.html
Copyright © 2011-2022 走看看